Elasticsearch 故障转移及水平扩容

发布于:2025-04-15 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、故障转移

Elasticsearch 的故障转移(Failover)机制是其高可用性的核心,通过分布式设计、自动检测和恢复策略确保集群在节点故障时持续服务。

1.1 故障转移的核心组件
组件 作用
Master 节点 管理集群状态(分片分配、索引创建)、协调故障转移
Data 节点 存储分片数据,参与分片复制
Zen Discovery 7.x 之前版本的节点发现和故障检测机制
Raft 协议 7.x+ 版本用于 Master 选举的共识算法
分片副本(Replicas) 数据冗余的基础,主分片故障时副本自动晋升
1.2 故障检测机制
  1. 心跳检测(Ping)

    • 检测方式:节点间定期发送心跳(默认间隔 1s,超时 30s)。
    • 关键参数:
      discovery.zen.fd.ping_interval: 1s      # 心跳间隔
      discovery.zen.fd.ping_timeout: 30s      # 超时判定
      discovery.zen.fd.ping_retries: 3        # 重试次数
      
  2. Master 选举

    • 7.x 之前版本:基于 discovery.zen.minimum_master_nodes(防止脑裂)。
    • 7.x+ 版本:使用 Raft 协议自动选举,需配置 cluster.initial_master_nodes。
1.3 故障转移流程

场景1:Data 节点故障

  1. 检测阶段:Master 节点检测到 Data 节点心跳丢失(超时 30s)。
  2. 分片重新分配:
    • 若故障节点包含主分片,其对应的副本分片自动晋升为新主分片。
    • 若副本不足,集群状态变为 yellow。
  3. 恢复新副本:Master 在健康节点上创建新的副本分片,恢复 green 状态。

场景2:Master 节点故障

  1. 选举触发:剩余 Master 候选节点发起新一轮选举(基于 Raft 协议)。
  2. 新 Master 生效:当选节点接管集群状态管理。
  3. 元数据同步:新 Master 从全局集群状态恢复分片分配信息。

场景3:网络分区(Split-Brain)

  1. 防护机制:
    • 7.x 之前:minimum_master_nodes 阻止少数派选举。
    • 7.x+:Raft 协议自动隔离少数派分区。
  2. 恢复:网络恢复后,少数派节点重新加入集群并同步数据。
1.4 手动故障转移场景与操作
  1. 节点计划性维护(如升级)

    # 1. 排除节点分片分配
    PUT _cluster/settings
    {
      "persistent": {
        "cluster.routing.allocation.exclude._name": "es-old-node"
      }
    }
    
    # 2. 等待分片迁移完成(检查无分片在此节点)
    GET _cat/shards?v&h=index,shard,node
    
    # 3. 安全停止节点
    docker stop es-old-node
    
  2. 分片强制分配(自动恢复失败时)

    # 手动分配未分配的分片
    POST /_cluster/reroute
    {
      "commands": [
        {
          "allocate_stale_primary": {
            "index": "logs-2023-10",
            "shard": 0,
            "node": "es-new-node",
            "accept_data_loss": true  # 仅在必要时使用!
          }
        }
      ]
    }
    
1.5 故障转移配置优化
  1. 控制分片恢复速度

    # 避免瞬时带宽和 CPU 过载
    cluster.routing.allocation.node_initial_primaries_recoveries: 4
    cluster.routing.allocation.node_concurrent_recoveries: 2
    indices.recovery.max_bytes_per_sec: 100mb
    
  2. 延迟分片分配(应对短暂故障)

    # 默认 1m,可延长至 5m 避免频繁迁移
    index.unassigned.node_left.delayed_timeout: 5m
    
  3. 优先恢复主分片

    cluster.routing.allocation.enable: "primaries"
    
1.6 故障转移注意事项
  1. 避免脑裂:合理配置 discovery.zen.minimum_master_nodes(通常为 (master_eligible_nodes / 2) + 1)。
  2. 副本分片数量:设置 number_of_replicas ≥ 1,确保每个主分片有至少一个副本。
  3. 分片均衡:避免热点分片集中,合理设计索引和分片数量。
  4. 慢恢复问题:大规模分片恢复可能影响性能,可通过 cluster.routing.allocation.node_concurrent_recoveries 限制并发恢复数。
  5. 跨可用区部署:通过 awareness 配置将分片分布到不同机架或可用区(AZ),避免单点故障。

二、水平扩容

Elasticsearch 的水平扩容(Horizontal Scaling)是通过增加节点数量来扩展集群的处理能力和存储容量,以应对数据量增长或高并发请求的场景。其核心思想是利用分布式架构的特性,将数据和负载均匀分配到更多节点上。

2.1 水平扩容的核心原理

Elasticsearch 的分布式架构天然支持水平扩容,关键点包括:

  1. 分片(Shard)机制:索引被拆分为多个主分片(Primary Shard)和副本分片(Replica Shard),分片分布在集群的各个节点。
  2. 自动负载均衡:新增节点后,Elasticsearch 会自动将部分分片迁移到新节点,实现负载均衡。
  3. 无缝扩展:扩容过程对用户透明,无需停机或手动干预数据迁移。
2.2 水平扩容的典型场景
  1. 存储容量不足:原始节点磁盘空间不足,需增加节点扩展存储。
  2. 性能瓶颈:查询延迟高或写入吞吐量不足,需分散负载。
  3. 高可用性需求:通过更多节点提高副本分片数量,增强容错能力。
2.3 水平扩容的具体步骤

步骤 1:添加新节点到集群

  1. 配置新节点:
    • 在新节点上安装 Elasticsearch,确保以下配置与现有集群一致:
      # elasticsearch.yml
      cluster.name: my-cluster      # 集群名称必须一致
      discovery.seed_hosts: ["node1_ip:9300", "node2_ip:9300"]  # 现有集群节点地址
      
      • 若新节点是数据节点,确保 node.roles: [ data ](默认角色)。
      • 若新节点是专用主节点或协调节点,需显式配置角色。
  2. 启动新节点:
    • 新节点会自动加入集群,并接收分片分配任务。

步骤 2:调整分片分配策略
Elasticsearch 默认会自动将分片分配到新节点,但可以通过配置优化:

  • 延迟分片分配(避免瞬时负载激增):

    PUT /_cluster/settings
    {
      "transient": {
        "cluster.routing.allocation.node_initial_primaries_recoveries": 1,  // 单节点并行恢复主分片数
        "cluster.routing.allocation.cluster_concurrent_rebalance": 2         // 并发分片迁移数
      }
    }
    
  • 排除旧节点(逐步迁移):

    PUT /_cluster/settings
    {
      "persistent": {
        "cluster.routing.allocation.exclude._ip": "old_node_ip"  // 从旧节点移出分片
      }
    }
    

步骤 3:调整索引分片数

  • 新建索引时指定分片数:
    水平扩容前需合理规划主分片数量(主分片数在创建索引后不可修改):

    PUT /my_index
    {
      "settings": {
        "number_of_shards": 6,    // 主分片数需提前规划
        "number_of_replicas": 1   // 副本分片数可动态调整
      }
    }
    
  • 动态调整副本分片数(即时生效):

    PUT /my_index/_settings
    {
      "number_of_replicas": 2     // 增加副本分片,提升容错和读取性能
    }
    

步骤 4:触发分片重平衡

  • 自动均衡:
    • 默认情况下,Elasticsearch 会在节点加入集群后自动迁移分片。
  • 手动触发:
    • 若需强制重新分配分片,使用 _cluster/reroute API:
      POST /_cluster/reroute
      {
        "commands": [
          {
            "move": {
              "index": "my_index",
              "shard": 0,
             "from_node": "old_node",
            "to_node": "new_node"
            }
          }
        ]
      }
      
2.4 扩容后的优化策略
  1. 分片设计优化

    • 主分片数:
      • 建议每个分片大小在 10GB-50GB 之间(避免过大导致迁移慢)。
      • 主分片数应与数据增长预期匹配,通常可按 数据总量 / 30GB 估算。
    • 副本分片数:
      • 增加 number_of_replicas 可提高读取吞吐量和容错能力,但会占用更多存储。
  2. 跨节点负载均衡

    • 分片分配过滤:
      • 通过 awareness 配置实现跨机架或可用区(AZ)分布:
      # elasticsearch.yml
      cluster.routing.allocation.awareness.attributes: rack  # 按机架感知分配
      node.attr.rack: rack1                                  # 节点所属机架
      
    • 热冷分离架构:
      • 使用 ILM(Index Lifecycle Management) 将冷数据迁移到低成本节点。
2.5 水平扩容的注意事项
  1. 主分片数不可变:
    • 索引的主分片数量在创建后无法修改,需提前规划或通过 Reindex API 重建索引。
  2. 网络与硬件一致性:
    • 新节点的硬件配置(如磁盘类型、CPU)应与旧节点尽量一致,避免性能瓶颈。
  3. 脑裂风险:
    • 扩容主节点时,确保 discovery.zen.minimum_master_nodes(7.x 之前版本)配置正确,防止多主节点冲突。
  4. 分片分布均匀性:
    • 避免分片集中在少数节点,可通过 _cluster/allocation/explain 分析未分配分片的原因。

网站公告

今日签到

点亮在社区的每一天
去签到