Elastic Stack梳理:集群搭建指南之高可用架构与实战部署

Linux搭建es集群详细教程(最终版) Linux搭建es集群详细步骤 今天写一篇Linux环境下搭建es集群文章,避免大家踩坑。es集群是在单机版es的基础上的,所以下面我们先开始搭建单机版es。 步骤: 1、下载或者上传安装包 下载安装包传送门: 2、解压安装包 3、创建普通用户 4、为新用户收钱 ... 阅读详情

分布式架构与Cerebro部署


1 ) 分布式基础

Elasticsearch(ES)通过分片(Shard)和副本(Replica)实现分布式存储与计算。数据被拆分为多个分片分散在不同节点,每个分片的副本提供高可用

集群由三种角色节点组成:

  • 主节点(Master):管理集群状态、分片分配
  • 数据节点(Data):存储分片数据,执行读写操作
  • 协调节点(Coordinating):接收客户端请求,路由到数据节点并聚合结果

2 ) Cerebro部署策略

  • 作用:用于监控集群健康、管理索引、重定位分片
  • 部署位置:独立于ES集群的专用机器(如192.168.1.100),无需在每个节点部署
  • 发现集群:通过连接任意ES节点(推荐协调节点)的HTTP端口(9200)自动发现全集群
  • 官网地址:https://github.com/lmenezes/cerebro

3 )Cerebro 部署

# 在独立机器执行 
wget https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.tgz 
tar -zxvf cerebro-*.tgz
cd cerebro-0.9.4
./bin/cerebro -Dhttp.port=9000 

集群拓扑规划与IP分配


节点类型IP地址数量说明
主节点192.168.1.101 (102, 103)3管理集群元数据
数据节点192.168.1.104 (105)2存储分片数据
协调节点192.168.1.106 (107)2处理客户端请求
Nginx代理192.168.1.1001负载均衡与统一入口
Cerebro监控192.168.1.1001与Nginx共用机器
  • 协调节点说明:ES默认所有节点具备协调能力,但独立部署可隔离负载,提升性能
  • 注:还可加入一个 预处理节点(可选),按ETL负载独立部署 node.ingest: true

架构拓扑

用户
Nginx代理
协调节点1
协调节点2
数据节点1
数据节点2
主节点1
主节点2
主节点3
Cerebro监控

节点角色分工与部署原则


1 ) 专用主节点(Master-eligible Nodes)

  • 职责:集群状态管理、分片分配、节点协调
  • 部署要求:
    • 数量至少 3个(奇数),避免脑裂(如3/5/7)
    • 配置:低CPU/内存(如4C8G),无数据存储(node.data: false)

2 ) 数据节点(Data Nodes)

  • 职责:存储分片数据、执行CRUD/聚合操作
  • 部署要求:
    • 数量根据数据量及负载动态扩展,初始建议≥2个
    • 配置:高配置CPU、内存(建议≥64G)、SSD磁盘(避免NAS)
    • 参数:node.master: false, node.data: true

3 ) 协调节点(Coordinating Only Nodes)

  • 职责:接收客户端请求,分发查询并聚合结果
  • 部署要求:
    • 高并发集群必选(如QPS>5000),数量=数据节点×0.5(例:4数据节点配2协调节点)
    • 配置:高CPU/网络带宽,禁用数据角色(node.master: false, node.data: false)

4 ) 预处理节点(Ingest Nodes)

  • 职责:数据索引前处理(如格式转换、字段提取)
  • 部署要求:按ETL需求启用,可与协调节点复用
集群规模与数量公式

节点类型最小数量扩展公式关键参数示例
专用主节点3固定奇数(3/5/7)node.master: true
数据节点2按数据量/分片数增加node.data: true
协调节点可选数据节点数×0.5(高并发场景)node.roles: [ ]
预处理节点可选按ETL负载独立部署node.ingest: true

分片数量参考:

  • 单个分片容量建议 30-50GB
  • 总分片数 = 索引数 × (主分片数 × (1 + 副本数))
  • 单数据节点分片上限建议 ≤800(避免性能瓶颈)
关键配置优化

1 ) 防止脑裂:

  • 配置 discovery.zen.minimum_master_nodes: (master_nodes/2 + 1)(旧版)
  • 新版ES使用内置选举机制,但仍需奇数主节点

2 ) 硬件与路径:

  • 数据目录独立分区:path.data: /ssd_mount/elasticsearch/data
  • JVM内存 ≤ 32G(避免指针压缩失效)

3 ) 安全与维护:

  • 生产环境启用TLS证书加密通信
  • 定期监控分片均衡性,避免热点分片

总结建议

  • 中小集群(<10节点):3专用主节点 + N数据节点(按存储扩展) + 1协调节点(可选)。
  • 大型集群(>20节点):5专用主节点 + 分片感知的数据节点 + 独立协调层。
  • 弹性扩展:优先横向扩展数据节点,协调节点按QPS增长追加

附:官方生产检查清单 → Elasticsearch Production Deployment Checklist

高可用主节点配置


1 ) 奇数节点原则

主节点数量必须为奇数(如3、5),避免脑裂(Split-Brain)
选举算法要求过半票数(Quorum),奇数确保选举结果唯一

2 ) 配置示例(主节点elasticsearch.yml)

# 所有主节点共用配置
cluster.name: my-es-cluster
node.name: master-01             # 每个节点名称唯一(如master-02、master-03)
node.roles: [ master ]          # 仅作为主节点
network.host: 192.168.1.101     # 当前节点IP
discovery.seed_hosts:            # 所有主节点IP列表
  - 192.168.1.101:9300
  - 192.168.1.102:9300 
  - 192.168.1.103:9300
cluster.initial_master_nodes:    # 初始主节点名称列表 
  - master-01
  - master-02
  - master-03

其他节点配置看下面示例

Nginx代理配置详解

1 ) 代理目标与必要性

  • 代理对象:仅协调节点(非主节点/数据节点)
  • 作用:
    • 负载均衡:分散客户端请求到多个协调节点
    • 统一入口:客户端只需访问Nginx的IP
    • 安全隔离:屏蔽内部节点暴露
  • 部署位置:独立机器(192.168.1.100),避免资源竞争

2 ) Nginx配置(/etc/nginx/nginx.conf)

http {
  upstream es_coordinators {
    server 192.168.1.106:9200;  # 协调节点1
    server 192.168.1.107:9200;  # 协调节点2
    keepalive 32;
  }
  server {
    listen 9200;
    location / {
      proxy_pass http://es_coordinators;
      proxy_http_version 1.1;
      proxy_set_header Connection "";
    }
  }
}

关键点:

  • 仅代理协调节点,主节点和数据节点不暴露给客户端
  • 使用keepalive提升连接复用率

注:Nginx 集群不展开, 仅配合ES的集群搭建

集群健康与分片管理


1 ) 健康状态检查

  • 通过Nginx代理执行:
    curl http://192.168.1.100:9200/_cluster/health?pretty
    
  • 优势:避免单点故障,自动路由到健康节点

2 ) 分片与副本设置

  • 创建索引时配置:
    curl -XPUT http://192.168.1.100:9200/my_index -H 'Content-Type: application/json' -d'
    {
      "settings": {
        "number_of_shards": 2,    # 主分片数(建议=数据节点数)
        "number_of_replicas": 1   # 每个主分片的副本数
      }
    }'
    
  • 动态调整副本:
    curl -XPUT http://192.168.1.100:9200/my_index/_settings -H 'Content-Type: application/json' -d'
    { "number_of_replicas": 2 }'
    

节点间通信机制


新节点加入
向seed_hosts发送请求
现有Master响应
同步集群状态
加入集群环

或参考下面

客户端
协调节点
主节点/元数据
状态同步
  • 传输层协议: 节点间通过TCP端口9300通信(如主节点选举、数据复制)
  • 配置要求: 所有节点需在discovery.seed_hosts中列出主节点的IP:9300地址

1 ) 通信机制:

  • 基于Zen Discovery协议进行节点发现
  • 9300端口用于节点间通信(Gossip协议)
  • 9200端口处理客户端HTTP请求

2 ) 代理必要性:

  • 必需:生产环境必须通过Nginx/Haproxy暴露服务
  • 优势:
    • 隐藏集群内部拓扑
    • 实现负载均衡和故障转移
    • 提供SSL/TLS加密终端
  • 协调节点说明:ES 7.x+版本所有节点默认具备协调能力,专用协调节点仅需在超大规模集群中部署

CentOS集群搭建详细步骤


1 ) 系统准备(所有节点)

# 关闭防火墙与SELinux
systemctl stop firewalld && systemctl disable firewalld 
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
 
# 修改系统参数
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
sysctl -p

2 ) 安装Java与ES

# 安装OpenJDK 11
yum install -y java-11-openjdk
 
# 下载并安装ES
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.17.0-x86_64.rpm
rpm -ivh elasticsearch-7.17.0-x86_64.rpm

3 ) 配置节点角色

  • 数据节点配置(/etc/elasticsearch/elasticsearch.yml)

    node.name: data-01
    node.roles: [ data ]             # 仅作为数据节点 
    network.host: 192.168.1.102
    discovery.seed_hosts:            # 指向主节点
      - 192.168.1.101:9300
      - 192.168.1.102:9300
      - 192.168.1.103:9300
    
  • 协调节点配置

    node.roles: [ ]                  # 空角色表示仅协调
    
    • 协调节点完整版参考
      # 基础角色配置(必需)
      node.roles:  []  # 空数组表示仅作为协调节点 
       
      # 网络与发现配置(必需)
      cluster.name:  my-es-cluster  # 需与集群其他节点一致
      network.host:  192.168.1.103  # 当前节点IP 
      discovery.seed_hosts:          # 指向主节点的IP列表 
        - 192.168.1.101:9300 
        - 192.168.1.102:9300
        - 192.168.1.103:9300
       
      # JVM优化(推荐)
      -Xms4g -Xmx4g                # 协调节点需处理请求聚合,建议分配足够堆内存
       
      # 安全配置(若集群启用安全)
      xpack.security.enabled:  true  # 开启安全传输 
      xpack.security.transport.ssl.enabled:  true 
      

4 ) 启动集群

systemctl daemon-reload
systemctl enable elasticsearch
systemctl start elasticsearch

每台节点均启动

5 ) 验证集群状态

# 通过Nginx检查(输出green为正常)
curl http://192.168.1.100:9200/_cluster/health?pretty

# 或
curl http://192.168.1.100:9200/_cat/nodes?v

5 )说明

组件最佳实践
主节点3台奇数节点,独立部署避免混合角色
协调节点独立部署2台,通过Nginx负载均衡
数据节点至少2台,分片数匹配节点数量
代理层Nginx必需,仅代理协调节点
监控Cerebro独立部署,连接Nginx或协调节点

6 )故障排查提示:

  • 节点未加入集群?检查discovery.seed_hosts的IP和端口(9300)
  • 分片未分配?确保主节点存活且数据节点磁盘空间充足

node.roles 参数的完整类型说明及功能解析


node.roles 参数类型详解表

角色类型配置值核心功能适用场景与注意事项
主节点 (Master)[master]管理集群元数据、分片分配、节点状态监控、索引创建/删除。需奇数节点防脑裂。生产环境至少配置 3 个专用主节点,避免与数据节点混用
仅投票主节点[master, voting_only]参与选举投票但不能被选为主节点,降低硬件要求。超大规模集群中作为辅助节点,分担选举压力
数据节点 (Data)[data]存储分片数据、执行 CRUD/搜索/聚合操作。默认包含协调功能。通用场景,需高磁盘和内存资源
内容数据节点[data_content]存储用户创建的索引数据,支持基础数据操作。多层存储架构的必备角色,不可与 [data] 共存
热数据节点[data_hot]存储高频访问的实时数据(如日志流),需高性能 SSD。与 ILM(索引生命周期管理)配合,承载最新数据
温数据节点[data_warm]存储中期低频访问数据(如月度报表),配置中等(SATA 硬盘)。承接从热节点迁移的数据,优化存储成本
冷数据节点[data_cold]存储长期归档数据(如历史记录),使用高容量 HDD。数据只读,支持低频检索
协调节点[ ](空数组)默认角色,处理客户端请求路由、结果聚合,不存储数据。高并发集群需独立部署,避免数据节点过载
采集节点 (Ingest)[ingest]执行预处理管道(如数据转换、字段过滤),类似 Logstash Filter。需高 CPU 资源,可独立部署或与数据节点共存
机器学习节点[ml, remote_cluster_client]执行异常检测、预测分析等机器学习任务。需单独许可证,配置高内存和 CPU
转换节点[transform, remote_cluster_client]执行 Transforms API 请求,生成聚合指标。替代部分 Rollup 功能,用于离线分析
远程集群节点[remote_cluster_client]作为网关连接跨集群搜索(CCS)中的远程集群。需在 elasticsearch.yml 中配置远程集群信息

关键使用规则

1 ) 角色组合限制

  • 专用数据角色(data_hot/data_warm 等)不可与 [data] 共用
  • 主节点角色应独立配置,避免与数据节点混合(如 [master, data] 仅限测试环境)

2 ) 生产环境建议

# 专用主节点配置
node.roles: [master]  # 分配至独立高可用机器

# 数据节点配置(多层存储)
node.roles: [data_content, data_hot]  # 热层节点

3 ) 协调节点资源规划

  • 每 5-10 个数据节点配置 1 个专用协调节点(node.roles: []),提升请求吞吐量

4 ) 版本兼容性

  • ES 7.9+ 使用 node.roles 替代旧参数(如 node.master: true)

验证节点角色分配

通过 API 查看集群节点角色分布:

curl -XGET "http://192.168.1.101:9200/_nodes?filter_path=nodes.*.roles"

输出示例:

{
  "nodes": {
    "node-101": { "roles": ["master"] },
    "node-104": { "roles": ["data_content", "data_hot"] }
  }
}

运维提示:角色规划直接影响集群性能与稳定性,大型集群建议参考 Elasticsearch 官方角色文档

故障排查与维护技巧


1 ) 脑裂问题(Split-Brain)

  • 原因:网络分区导致多个主节点被选举
  • 解决方案:严格设置 discovery.zen.minimum_master_nodes: (master_num/2 + 1)
    • N/2 + 1 确定最小主节点数(如 3 节点集群需配置为 2)
    # 强制设置主节点
    POST /_cluster/reroute?retry_failed
    { "commands" : [
      { "move" : { "index" : "my_index", "shard": 0, "to_node" : "node-1" }}
    ]}
    
    或
    POST /_cluster/reroute
    {
      "commands": [
        {
          "move": {
            "index": "hot_index",
            "shard": 2,
            "from_node": "node1",
            "to_node": "node3"
          }
        }
      ]
    }
    

2 ) 数据一致性问题

  • 写入冲突解决:基于版本号(_version)的乐观锁控制
  • 读一致性:设置 replication=quorum 保证多数副本确认

3 ) 滚动重启步骤:

# 1. 禁用分片分配
PUT _cluster/settings { "transient": { "cluster.routing.allocation.enable":  "none" } }

# 2. 停止节点 -> 升级 -> 启动 
# 3. 重新启用分配
PUT _cluster/settings { "transient": { "cluster.routing.allocation.enable":  "all" } }

4 ) 集群健康状态:

健康状态三元组:

  • GREEN:所有主副分片均分配正常
  • YELLOW:主分片正常但副本未完全分配
  • RED:存在未分配的主分片(数据丢失风险)

健康检查API:

GET /_cluster/health

响应示例:

{
  "cluster_name": "my_cluster",
  "status": "yellow",
  "unassigned_shards": 3,
  "number_of_nodes": 2
}

故障转移处理流程


在这里插入图片描述

  • 剩余节点检测Master失联
  • 重新选举新Master节点
  • 将未分配主分片的副本提升为主分片
  • 在可用节点创建新副本
  • 状态转换:RED → YELLOW → GREEN
  • 关键特性:RED状态仍可服务可用分片数据,但存在数据缺失风险

ES集群关键配置

elasticsearch.yml 优化项:

# elasticsearch.yml  生产配置
cluster.name:  prod-cluster
node.name:  ${HOSTNAME}
node.master:  true

# 磁盘水位线(预防黄色状态)
cluster.routing.allocation.disk.watermark.low:  85%
cluster.routing.allocation.disk.watermark.high:  90%
cluster.routing.allocation.disk.threshold_enabled:  true

# 分片分配策略
cluster.routing.allocation.disk.threshold_enabled:  true
cluster.routing.allocation.disk.watermark.low:  "85%"
cluster.routing.allocation.disk.watermark.high:  "90%"
cluster.routing.allocation.same_shard.host:  true
indices.cluster.send_refresh_mapping:  false

# 线程池优化
thread_pool.write.queue_size:  1000
thread_pool.search.queue_size:  1000

# 容灾参数
cluster.routing.allocation.enable:  all
cluster.fault_detection.leader_check.interval:  5s
cluster.publish.timeout:  30s

运维最佳实践


1 ) 容量规划:

  • 每GB堆内存对应20-25个分片
  • 监控工具:ElasticHQ / Cerebro

2 ) 滚动重启流程:

# 禁用分片分配
# PUT _cluster/settings
{"transient":{"cluster.routing.allocation.enable":"none"}} 

# 重启节点
systemctl restart elasticsearch

# 启用分片分配
# PUT _cluster/settings
{"transient":{"cluster.routing.allocation.enable":"all"}} 

3 ) 灾难恢复:

# 注册快照仓库
PUT _snapshot/my_backup
{
  "type": "fs",
  "settings": {"location": "/mnt/es_backups"}
}

# 创建快照
PUT _snapshot/my_backup/snapshot_2023?wait_for_completion=true

4 ) 版本升级策略

备份快照
停用分片分配
逐节点滚动重启
启用分配并验证

ES集群运维命令手册


1 ) 分片分配控制

# 强制分配未分配分片
POST /_cluster/reroute?retry_failed

2 ) 磁盘阈值配置

PUT /_cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.disk.threshold_enabled":  false
  }
}

3 ) 节点角色查询

GET /_cat/nodes?v&h=name,role,shards

4 ) 启用分片分配过滤:避免分片分配到故障节点

# PUT /_cluster/settings  
{  
  "transient": {  
    "cluster.routing.allocation.exclude._ip":  "192.168.1.x" // 排除故障节点IP  
  }  
}

基于NestJS的ElasticSearch集成


1 )基础服务封装

// es.service.ts 
import { Injectable } from '@nestjs/common';
import { Client, ClientOptions } from '@elastic/elasticsearch';

@Injectable()
export class EsService {
  private readonly client: Client;

  constructor() {
    const options: ClientOptions = { 
      nodes: ['http://node1:5200', 'http://node2:5300'],
      maxRetries: 5,
      requestTimeout: 60000
    };
    this.client  = new Client(options);
  }

  // 创建索引
  async createIndex(index: string, body: any) {
    return this.client.indices.create({  index, body });
  }

  // 文档索引
  async indexDocument(index: string, id: string, document: object) {
    return this.client.index({  index, id, body: document });
  }
}

2 ) 集群健康监控与告警

import { Controller, Get } from '@nestjs/common';  
import { Client } from '@elastic/elasticsearch';  
 
@Controller('cluster')  
export class ClusterHealthController {  
  private readonly esClient: Client;  
 
  constructor() {  
    this.esClient  = new Client({ node: 'http://localhost:9200' });  
  }  
 
  @Get('health')  
  async getHealth() {  
    const { body } = await this.esClient.cluster.health();   
    if (body.status  === 'red') {  
      // 触发告警逻辑(如邮件/Slack通知)  
      this.triggerAlert('CRITICAL:  Cluster status RED - Unassigned primary shards');  
    }  
    return body;  
  }  
 
  private triggerAlert(message: string) {  
    // 集成第三方告警服务(如SendGrid/PagerDuty)  
    console.error(`ALERT:  ${message}`);  
  }  
}  

3 )动态分片再平衡

场景:节点扩容后自动优化分片分布

import { Injectable } from '@nestjs/common';  
import { Client } from '@elastic/elasticsearch';  
 
@Injectable()  
export class ShardRebalanceService {  
  private readonly esClient: Client;  
 
  constructor() {  
    // 这里连的不是 Nginx,而是 协调节点,也可以使用 Nginx 但是需要 node:{} 这样配置
    this.esClient  = new Client({ nodes: ['http://node1:9200', 'http://node2:9200'] });  
  }  
 
  async rebalanceShards(index: string) {  
    // 1. 检查未分配分片  
    const { body } = await this.esClient.cat.shards({  format: 'json' });  
    const unassignedShards = body.filter(shard  => shard.state  !== 'STARTED');  
 
    // 2. 手动分配分片到新节点  
    if (unassignedShards.length  > 0) {  
      await this.esClient.cluster.reroute({   
        body: {  
          commands: unassignedShards.map(shard  => ({  
            allocate_replica: {  
              index: shard.index,   
              shard: shard.shard,   
              node: "new_node_id"  // 新增节点ID  
            }  
          }))  
        }  
      });  
    }  
  }  
}

4 )集群状态监控

// cluster-monitor.service.ts 
import { Injectable } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';

@Injectable()
export class ClusterMonitorService {
  constructor(private readonly esClient: Client) {}

  async getClusterHealth() {
    return this.esClient.cluster.health(); 
  }

  async getShardAllocation() {
    return this.esClient.cat.allocation({  format: 'json' });
  }

  async relocateShard(shard: number, fromNode: string, toNode: string) {
    return this.esClient.cluster.reroute({ 
      body: {
        commands: [
          {
            move: {
              index: "my_index",
              shard,
              from_node: fromNode,
              to_node: toNode
            }
          }
        ]
      }
    });
  }
}

或

集群监控与自动恢复

// cluster-monitor.service.ts 
import { Injectable, Logger } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';

@Injectable()
export class ClusterMonitor {
  private readonly logger = new Logger(ClusterMonitor.name); 
  private readonly client: Client;

  constructor() {
    this.client  = new Client({ nodes: ['http://填入ip:填入port'] });
  }

  async checkShardAllocation() {
    const { body } = await this.client.cat.allocation({  format: 'json' });
    const unassigned = body.filter((node:  any) => node.shards  === '0');
    
    if (unassigned.length  > 0) {
      this.logger.warn(`Unassigned  shards detected: ${unassigned.length}`); 
      await this.client.cluster.reroute({ 
        body: {
          commands: unassigned.map((node:  any) => ({
            allocate_stale_primary: {
              index: node.index, 
              shard: node.shard, 
              node: node.node, 
              accept_data_loss: true
            }
          }))
        }
      });
    }
  }
}

5 ) 集群配置管理

// cluster-config.service.ts 
import { Injectable } from '@nestjs/common';
import { Client } from '@elastic/elasticsearch';

@Injectable()
export class ClusterConfigService {
  private readonly client: Client;

  constructor() {
    this.client  = new Client({ node: 'http://localhost:5200' });
  }

  async disableDiskThreshold() {
    // 关闭磁盘空间阈值限制
    await this.client.cluster.putSettings({ 
      body: {
        persistent: {
          "cluster.routing.allocation.disk.threshold_enabled":  false
        }
      }
    });
  }
}

6 ) 智能分片管理:根据数据类型自动分配热/冷节点

async createTimeSeriesIndex(index: string) {
  return this.esService.indices.create({ 
    index,
    body: {
      settings: {
        number_of_shards: 12,
        number_of_replicas: 1,
        "index.routing.allocation.include._tier_preference":  "data_hot"
      }
    }
  });
}

7 ) 批量操作优化:使用管道技术提升吞吐量

const BATCH_SIZE = 500;
 
async bulkIndexWithRetry(index: string, documents: any[]) {
  for (let i = 0; i < documents.length;  i += BATCH_SIZE) {
    const batch = documents.slice(i,  i + BATCH_SIZE);
    await this.esService.bulk({ 
      body: batch.flatMap(doc  => [{ index: { _index: index } }, doc])
    });
  }
}

8 ) 灾难恢复机制:集成快照API

async restoreSnapshot(repo: string, snapshot: string) {
  return this.esService.snapshot.restore({ 
    repository: repo,
    snapshot,
    body: {
      indices: '*',
      include_global_state: true 
    }
  });
}

9 ) 断路保护

// 使用circuit-breaker-js
import circuitBreaker from 'circuit-breaker-js';
 
const breaker = new circuitBreaker();
 
async safeEsOperation() {
  return breaker.run({ 
    execute: () => this.esService.search(/*  ... */),
    fallback: () => ({ error: 'Service unavailable' })
  });
}

10 )自动重试策略

async resilientSearch(query: SearchQueryDto, retries = 3) {
  try {
    return await this.search(query); 
  } catch (e) {
    if (retries > 0 && e.message.includes('ES_CONNECTION_FAILED'))  {
      await new Promise(resolve => setTimeout(resolve, 1000));
      return this.resilientSearch(query,  retries - 1);
    }
    throw e;
  }
}

11 ) 性能优化

// 深度分页处理 
async scrollSearch(index: string, query: any) {
  const scroll = '1m';
  const response = await this.esService.search({ 
    index,
    scroll,
    body: query
  });
 
  const results = [];
  let scrollId = response._scroll_id;
 
  while (results.length  < 10000) {
    const response = await this.esService.scroll({ 
      scroll_id: scrollId,
      scroll
    });
 
    results.push(...response.hits.hits); 
    
    if (response.hits.hits.length  === 0) break;
  }
  
  await this.esService.clearScroll({  scroll_id: scrollId });
  return results;
}

12 ) 动态索引策略

// 按时间创建索引
getTimeSeriesIndex(baseName: string) {
  const date = new Date();
  return `${baseName}-${date.getUTCFullYear()}.${(date.getUTCMonth()+1).toString().padStart(2,  '0')}`;
}

13 ) 高级应用

// src/elastic/elastic.service.ts 
import { Injectable } from '@nestjs/common';
import { ElasticsearchService } from '@nestjs/elasticsearch';
import { IndexDocumentParams, SearchResponse } from 'elasticsearch';
import { 
  CreateIndexDto, 
  DocumentDto,
  SearchQueryDto,
  UpdateDocumentDto 
} from './dto';
 
@Injectable()
export class ElasticService {
  constructor(private readonly esService: ElasticsearchService) {}
 
  /**
   * 创建索引(自动配置分片策略)
   * @param dto {index: 索引名, shards: 主分片数, replicas: 副本数}
   */
  async createIndex(dto: CreateIndexDto): Promise<any> {
    const { index, shards = 3, replicas = 1 } = dto;
    return this.esService.indices.create({ 
      index,
      body: {
        settings: {
          number_of_shards: shards,
          number_of_replicas: replicas,
          "index.routing.allocation.include._tier_preference":  "data_content,data_hot",
        }
      }
    });
  }
 
  /**
   * 索引文档(自动生成ID)
   * @param index 索引名称
   * @param document 文档内容 
   */
  async indexDocument(index: string, document: any): Promise<any> {
    return this.esService.index({ 
      index,
      body: document,
      refresh: 'wait_for' // 写入后立即刷新 
    });
  }
 
  /**
   * 批量索引文档(高性能写入)
   * @param index 索引名称
   * @param documents 文档数组 
   */
  async bulkIndex(index: string, documents: DocumentDto[]): Promise<any> {
    const body = documents.flatMap(doc  => [
      { index: { _index: index } },
      doc 
    ]);
    
    return this.esService.bulk({ 
      refresh: 'wait_for',
      body 
    });
  }
 
  /**
   * 全文检索(支持复杂查询)
   * @param dto 查询参数 
   */
  async search(dto: SearchQueryDto): Promise<SearchResponse<any>> {
    const { index, query, size = 10, from = 0 } = dto;
    return this.esService.search({ 
      index,
      body: {
        query: {
          bool: {
            must: [
              { 
                multi_match: {
                  query,
                  fields: ["title^3", "content"],
                  fuzziness: "AUTO"
                }
              }
            ],
            filter: [
              { range: { timestamp: { gte: "now-30d/d" } } }
            ]
          }
        },
        highlight: {
          fields: { content: {} }
        },
        aggs: {
          category_agg: {
            terms: { field: "category.keyword"  }
          }
        }
      },
      size,
      from
    });
  }
 
  /**
   * 获取集群健康状态
   */
  async clusterHealth(): Promise<any> {
    return this.esService.cluster.health(); 
  }
 
  /**
   * 分片重分配(运维接口)
   * @param index 索引名称
   */
  async rerouteShards(index: string): Promise<any> {
    return this.esService.cluster.reroute({ 
      body: {
        commands: [{
          move: {
            index,
            shard: 0,
            to_node: "data_node_1",
            from_node: "data_node_2"
          }
        }]
      }
    });
  }
}

深度总结


分布式集群设计精髓:

  • 分片(Shard)是水平扩展的基石
  • 分片数量直接决定数据分布粒度,需根据数据增长预期预先规划

副本(Replica)的双重价值:

  • 数据高可用:物理故障时的数据完整性保障
  • 读性能扩展:通过增加副本提升查询吞吐量

分片规划原则:

  • 主分片数量 = 索引创建时固定,需预估未来容量
  • 副本数量 = 可动态调整,建议 ≥1 保证高可用

扩容铁律:

  • 现有索引扩容 → 需重建索引
  • 读取吞吐提升 → 增加副本 + 补充节点

状态认知:

  • RED ≠ 服务不可用 → 检查unassigned_shards定位分片问题

节点角色的精细化控制

  • 生产环境建议:
    • 专用Master节点(3/5/7奇数台)
    • 纯Data节点集群
    • 独立Coordinating节点

集群状态管理的核心原则

  • 仅Master节点可修改Cluster State
  • 选举机制依赖discovery.seed_hosts 配置
  • 节点故障时副本自动晋升保障服务连续性
ELK集群搭建(基础教程) ELK集群搭建(基础教程) 目录: 机器准备 集群内各台机器安装Elasticsearch 安装部署Kafka(注:每个节点都配置,注意ip不同) 安装logstash工具 安装filebeat ELK收集Nginx的json日志 ELK收集Nginx正常日志和错误日志 ELK收集Tomcat日志 ELK收集docker日志 配置filebeat收集单个docker日志 modules日志收集 使用redis作为缓存收集日志 使用Kafka做缓存收集日志 阅读详情

相关推荐

Elastic Meetup广州站:技术交流与实战分享

Elasticsearch作为分布式搜索和分析引擎,广泛应用于日志管理、安全监控和业务搜索等场景。其核心原理基于倒排索引和分布式计算,能够高效处理海量数据。通过Elastic Stack(包括Elasticsearch、Kibana等组件),开发者可以实现实时数据分析和可视化。技术社区线下沙龙如Elastic Meetup,为开发者提供了深度交流的平台,涵盖最新版本特性、性能调优和行业应用案例。2026年广州站活动将聚焦多模态搜索、全栈链路追踪等前沿话题,帮助参会者提升技术实践能力。

weixin_29035147的博客 165

Elastic stack(一):Elastic stack简介、Elasticsearch简介、安装

ELK是三款软件的简称,分别是Elasticsearch、Logstash、Kibana,在发展的过程中,又有新成员Beats的加入,所以就形成了Elastic Stack。说白了Elastic Stack相当于以前的ELK。Elasticsearch是Elastic Stack的核心,是一个分布式搜索和分析引擎。Logstash和Beats有助于收集、聚合和丰富数据,并将其存储在Elasticsearch中。Kibana让你 以交互方式探索、可视化和共享数据的见解,并管理和监控整个堆栈。

dl_11的博客 4306

阿里云Elasticsearch从零搭建:避坑指南与Kibana登录全流程

Elasticsearch作为基于Lucene的分布式搜索引擎,其核心原理是通过倒排索引实现近实时的海量数据检索与分析。在技术价值上,它提供了高可扩展性和强大的全文搜索能力,广泛应用于日志分析、应用性能监控等场景。当结合云服务如阿里云Elasticsearch时,用户可享受免运维、开箱即用的优势,但网络配置与安全策略成为关键实践环节。本文聚焦于阿里云Elasticsearch实例的创建、专有网络(VPC)配置及安全组策略设置,并详细演示如何通过访问白名单配置,最终成功登录Kibana可视化控制台,帮助开发者

weixin_33892359的博客 415

Elastic Stack 概述

文章目录一、Elastic Stack简介三、elasticsearch四、logstash二、Beats五、kibana六、常见架构 一、Elastic Stack简介 “ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用

weixin_45880055的博客 3555

ElasticStack实战:从零搭建日志分析平台与核心组件部署指南

日志管理与数据分析是现代运维和开发中的基础需求,其核心在于对海量、分散的日志数据进行高效的采集、存储、检索与可视化。ElasticStack(常称ELK Stack)作为一套成熟的开源技术栈,完美回应了这一需求。其技术原理基于分布式搜索引擎Elasticsearch提供近实时的全文搜索与聚合分析能力,配合轻量级数据采集器Beats和强大的数据管道处理工具Logstash,实现了从数据源到洞察的完整链路,并通过Kibana提供直观的可视化界面。这套组合的技术价值在于能够处理PB级数据,极大地提升了故障排查、业

weixin_30512089的博客 647

第十阶段【Elasticsearch基础及运维】04:Elasticsearch集群的部署

Elasticsearch集群的部署

weixin_40612128的博客 238

Elastic Stack梳理: 生产环境部署与性能优化深度指南之从集群配置到读写调优实战

Elasticsearch生产环境部署与优化指南 本文系统介绍了Elasticsearch生产环境的关键配置与性能优化策略。首先强调系统级参数优化:禁用Swap、调整文件描述符限制、优化虚拟内存和JVM堆内存(不超过31GB)。在静态配置方面,建议精简elasticsearch.yml,仅保留必要参数,并通过API调整动态参数。 针对写性能优化,提出三阶段策略:客户端使用Bulk API批量写入(10-20MB/批次);服务端通过调整Refresh间隔(30s)、Translog异步化(120s刷盘)和分片

Wang的专栏 1767

Flutter蓝牙开发实战:flutter_blue_plus核心功能与实现原理剖析

本文深入剖析了Flutter蓝牙开发插件flutter_blue_plus的核心功能与实现原理。文章从源码解析入手,详细讲解了蓝牙状态管理、设备扫描、GATT连接、服务发现以及数据读写等关键流程的实现机制,并分享了实战中的性能调优与常见问题解决方案,帮助开发者高效构建跨平台蓝牙应用。

weixin_29014237的博客 444

使用 Helm Chart 在 Kubernetes 上部署 ELK 日志栈:elastic-stack 聚合 Chart 实战指南

本指南围绕 charts 仓库中 `elastic-stack` Helm Chart 展开,系统讲解如何通过一个聚合 Chart 在 Kubernetes 上一次性部署 Elasticsearch 集群、Kibana 与 Logstash(ELK),以及如何按需启用或替换 Fluentd、Filebeat、Elasticsearch Curator、Nginx LDAP 认证代理等周边组件。读完

gitblog_00937的博客 1015

毫米波与太赫兹:十射线模型建模

Pt=1,只考虑地面和前后两面墙的反射,反射系数为0.7。用matlab设计程序并实现该功能。,总计考虑10条路径,求出接收功率随。

SupermarketX的博客 786

JAVA进阶面试题:如何设计一个高并发系统?

如何设计一个高并发系统? 面试官心理分析 说实话,如果面试官问你这个题目,那么你必须要使出全身吃奶劲了。为啥?因为你没看到现在很多公司招聘的 JD 里都是说啥,有高并发就经验者优先。 如果你确实有真才实学,在互联网公司里干过高并发系统,那你确实拿 offer 基本如探囊取物,没啥问题。面试官也绝对不会这样来问你,否则他就是蠢。 假设你在某知名电商公司干过高并发系统,用户上亿,一天流量几十亿,高峰期并发量上万,甚至是十万。那么人家一定会仔细盘问你的系统架构,你们系统啥架构?怎么部署的?部署了多少台机器

uuop155的博客 1023

diagrams 绘制 Elastic 云架构图:elastic provider 全部节点类完整参考与实战指南

在 [diagrams](https://link.gitcode.com/i/4c2ee9640ab970ab3ce1b4a6738cf32d)(Diagram as Code)项目中,`elastic` 是与 AWS、GCP、K8s 等并列的内置 provider,用于把 Elastic 技术栈中的 Agent、Beats、Elasticsearch、Enterprise Search、可观测

gitblog_00848的博客 769

GD32F303串口DMA发送数据避坑指南:为什么你的发送函数会卡住?

本文深入解析GD32F303单片机串口DMA发送数据时常见的卡死问题,提供详细的避坑指南。从DMA传输完成中断时序、发送状态管理到双通道DMA的特别注意事项,全面剖析问题根源并给出解决方案,帮助开发者构建健壮的DMA发送机制。

weixin_27038245的博客 298

Elastic Stack 技术栈与无服务器架构核心指南

本文档系统梳理Elastic Stack(ELK栈)全组件体系、核心能力、数据接入方案,以及标准化的安装部署规范,所有Elastic部署形态与项目均基于统一的开源技术底座构建,同时支持无服务器(Serverless)化部署方案,并结合各模块核心能力配套企业级实际落地案例,实现技术原理与业务实践的深度结合。

海兰 649

主成分分析(PCA)和局部线性嵌入(LEE)原理详解

从KNN谈“维度灾难”,介绍线性降维PCA和局部线性嵌入LLE 这两种降维方法的原理

superzzx0920的博客 5617

智能排班考勤系统原型

可实现从业务预测,到工时预估,再到人员分配全流程自动智能排班。可应用于客服行业或工厂的智能排班系统。

gywm15111336483的专栏 996

Kibana:功能全景梳理/Elastic Stack可视化管理平台

摘要: Kibana是Elasticsearch的核心可视化运维平台,提供数据检索、监控分析、集群管理等功能。其核心模块分为: 数据接入(首页):支持样本数据导入、本地文件上传及现有ES索引对接,需通过Index Patterns建立字段映射; 数据探索(Discover/Dashboard):日志查询、可视化图表制作、APM链路追踪及自定义大屏(Canvas); 集群管理(Console/Monitoring):ES索引调试、集群监控、权限配置及冷数据归档(Rollups); 扩展功能:告警(Alerti

snow的博客 689

手把手教你学Simulink--基于Simulink的高速公路自动驾驶场景仿真建模

特点车道保持:自动调整车辆方向以保持在车道中央。自适应巡航控制(ACC):根据前方车辆的速度自动调节车速。换道辅助:安全地变换车道以超过慢速行驶的车辆或准备驶离高速公路。紧急制动:检测潜在碰撞并采取措施避免事故。挑战安全性:确保所有功能在各种条件下都能可靠运行。实时性:处理大量传感器数据,并迅速做出反应。复杂性:集成多个子系统,包括感知、规划与控制。首先明确要模拟的任务内容。车辆需保持在车道内行驶。根据交通情况自动调整速度。安全地执行换道操作。在必要时实施紧急制动。

MHD0815的博客 248

腾讯云下部署 Elastic Stack 各种 Beat 的最佳实践

概述 使用 Elastic Stack 的各种 Beats 模块可以彻底的终结在服务器上手工捞日志查指标的扭曲实践。利用腾讯云提供的 Elasticsearch 服务,可以轻松搞定大规模云环境的运维。本文一次性的帮你梳理清楚了,必备的基础操作,确保你能用 Elastic Stack 安全、稳定和扩展的持续监控你的生产环境。 创建 ES 集群 登录腾讯云服务控制台,查询并进入 Elasticsearc 服务,点击新建按钮,创建 Elasticsearch 集群。如下图所示。 集群配置说明: .

DevOps 教练 502

手把手教你学Simulink——基于自动驾驶辅助系统的场景实例:车道保持辅助系统(LKA)的仿真与实现

本文通过Simulink实例讲解车道保持辅助系统(LKA)的实现方法。首先介绍LKA从预警到主动控制的技术演进,阐述其系统架构、核心组件和工作原理。重点演示基于自行车模型的车辆横向动力学建模过程,以及使用线性二次调节器(LQR)设计横向控制器的详细步骤。教程包含四个仿真场景测试,分析关键指标如控制精度、舒适性和响应性。最后探讨LKA技术的发展方向,强调人机协同的安全理念。该实例为自动驾驶辅助系统开发提供了完整的Simulink实践方案。

MHD0815的博客 182

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Windows系统部署Elastic Stack 8.x:从Java环境配置到Kibana连接实战指南

Elasticsearch作为基于Lucene构建的分布式搜索与分析引擎,其核心原理是通过倒排索引实现海量数据的近实时检索与复杂聚合分析。这一技术为日志分析、指标监控和全文搜索等场景提供了强大的数据处理能力,极大地提升了运维效率和数据分析深度。在本地开发与测试环境中,开发者常需在熟悉的操作系统上快速搭建可控的轻量级技术栈。本文聚焦于在Windows平台部署Elastic Stack 8.x的完整流程,详细解析了Java环境配置、Elasticsearch与Kibana版本一致性、核心配置文件调整等关键步骤,

weixin_34203832的博客 336

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【Elasticsearch从入门到精通】第52篇:Elastic Stack全景解读——ES、Logstash、Beats与Kibana的协作

摘要 Elastic Stack(ELK)是一个完整的日志管理解决方案,由Elasticsearch、Logstash、Kibana和Beats四大核心组件构成。本文系统性地介绍了各组件在数据处理流程中的定位:Beats负责轻量级数据采集(包括文件日志、系统指标、网络数据等),Logstash进行复杂的过滤转换,Elasticsearch提供分布式存储与检索,Kibana实现可视化分析。重点剖析了Beats家族的7种数据采集器(Filebeat、Metricbeat等)及其适用场景,对比了Logstash与

xyghehehehe的专栏 245

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Elastic Stack梳理:正排索引与倒排索引深度解析及Elasticsearch工程实践指南

搜索引擎索引机制通过正排索引(文档ID→内容)和倒排索引(关键词→文档ID)协同工作,实现高效检索。正排索引类似书籍目录,倒排索引类似索引页,两者配合将查询复杂度从O(n)降至O(log n)。Elasticsearch采用字段级索引,每个字段独立构建倒排索引,支持精准查询。工程实践中,NestJS集成Elasticsearch需要配置集群环境、创建索引(含分词设置)、实现批量写入和高级查询(如短语搜索与高亮)。生产环境需优化参数(如refresh_interval、缓存设置)并实施安全加固(启用SSL)。

Wang的专栏 2387

Elastic Stack梳理:Kibana 核心功能解析之配置管理、索引模式与数据探索实战

Kibana基础配置详解了核心配置文件kibana.yml的关键参数设置,包括网络配置、Elasticsearch连接、超时控制和日志管理等。生产环境推荐使用专用协调节点架构,以提升查询稳定性。索引模式管理支持通配符匹配和时间字段设置,并提供字段格式化和脚本字段功能。Discover模块支持时间过滤、查询语法切换和字段分析等数据探索功能。通过合理的配置和架构设计,可优化Kibana的性能和可用性。

Wang的专栏 384

手把手elasticsearch学习之本地化部署数据导入架构全量详解

本文基于场景,系统梳理并深度阐述Elastic官方提供的全量数据导入架构体系,完整覆盖无服务器(Serverless)、Elastic Stack堆叠两大核心部署形态,以及适配不同网络环境、业务用例的细分数据导入方案,明确各架构的适用边界、部署逻辑、核心能力与选型决策依据。

海兰 391

Wazuh实战指南:从安装配置到安全响应全解析

本文提供了一份全面的Wazuh实战指南,涵盖从安装配置到核心功能应用的完整流程。详细解析了Wazuh作为一体化安全监控平台的核心价值,包括入侵检测、日志分析、文件完整性监控和合规性检查。通过分步部署方案、核心功能配置及主动响应实战,帮助用户快速构建企业级安全监控与自动化响应能力。

gin88的博客 702
上一篇: Elastic Stack梳理:查询API深度解析与工程实践全指南
下一篇: Elastic Stack梳理:核心机制深度解析之倒排索引、实时性与数据持久化优化
Wang's Blog
博客等级 码龄12年 7434粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值