一、故障转移
Elasticsearch 的故障转移(Failover)机制是其高可用性的核心,通过分布式设计、自动检测和恢复策略确保集群在节点故障时持续服务。
1.1 故障转移的核心组件
组件 | 作用 |
---|---|
Master 节点 | 管理集群状态(分片分配、索引创建)、协调故障转移 |
Data 节点 | 存储分片数据,参与分片复制 |
Zen Discovery | 7.x 之前版本的节点发现和故障检测机制 |
Raft 协议 | 7.x+ 版本用于 Master 选举的共识算法 |
分片副本(Replicas) | 数据冗余的基础,主分片故障时副本自动晋升 |
1.2 故障检测机制
-
心跳检测(Ping)
- 检测方式:节点间定期发送心跳(默认间隔 1s,超时 30s)。
- 关键参数:
discovery.zen.fd.ping_interval: 1s # 心跳间隔 discovery.zen.fd.ping_timeout: 30s # 超时判定 discovery.zen.fd.ping_retries: 3 # 重试次数
-
Master 选举
- 7.x 之前版本:基于 discovery.zen.minimum_master_nodes(防止脑裂)。
- 7.x+ 版本:使用 Raft 协议自动选举,需配置 cluster.initial_master_nodes。
1.3 故障转移流程
场景1:Data 节点故障
- 检测阶段:Master 节点检测到 Data 节点心跳丢失(超时 30s)。
- 分片重新分配:
- 若故障节点包含主分片,其对应的副本分片自动晋升为新主分片。
- 若副本不足,集群状态变为 yellow。
- 恢复新副本:Master 在健康节点上创建新的副本分片,恢复 green 状态。
场景2:Master 节点故障
- 选举触发:剩余 Master 候选节点发起新一轮选举(基于 Raft 协议)。
- 新 Master 生效:当选节点接管集群状态管理。
- 元数据同步:新 Master 从全局集群状态恢复分片分配信息。
场景3:网络分区(Split-Brain)
- 防护机制:
- 7.x 之前:minimum_master_nodes 阻止少数派选举。
- 7.x+:Raft 协议自动隔离少数派分区。
- 恢复:网络恢复后,少数派节点重新加入集群并同步数据。
1.4 手动故障转移场景与操作
-
节点计划性维护(如升级)
# 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
-
分片强制分配(自动恢复失败时)
# 手动分配未分配的分片 POST /_cluster/reroute { "commands": [ { "allocate_stale_primary": { "index": "logs-2023-10", "shard": 0, "node": "es-new-node", "accept_data_loss": true # 仅在必要时使用! } } ] }
1.5 故障转移配置优化
-
控制分片恢复速度
# 避免瞬时带宽和 CPU 过载 cluster.routing.allocation.node_initial_primaries_recoveries: 4 cluster.routing.allocation.node_concurrent_recoveries: 2 indices.recovery.max_bytes_per_sec: 100mb
-
延迟分片分配(应对短暂故障)
# 默认 1m,可延长至 5m 避免频繁迁移 index.unassigned.node_left.delayed_timeout: 5m
-
优先恢复主分片
cluster.routing.allocation.enable: "primaries"
1.6 故障转移注意事项
- 避免脑裂:合理配置 discovery.zen.minimum_master_nodes(通常为 (master_eligible_nodes / 2) + 1)。
- 副本分片数量:设置 number_of_replicas ≥ 1,确保每个主分片有至少一个副本。
- 分片均衡:避免热点分片集中,合理设计索引和分片数量。
- 慢恢复问题:大规模分片恢复可能影响性能,可通过 cluster.routing.allocation.node_concurrent_recoveries 限制并发恢复数。
- 跨可用区部署:通过 awareness 配置将分片分布到不同机架或可用区(AZ),避免单点故障。
二、水平扩容
Elasticsearch 的水平扩容(Horizontal Scaling)是通过增加节点数量来扩展集群的处理能力和存储容量,以应对数据量增长或高并发请求的场景。其核心思想是利用分布式架构的特性,将数据和负载均匀分配到更多节点上。
2.1 水平扩容的核心原理
Elasticsearch 的分布式架构天然支持水平扩容,关键点包括:
- 分片(Shard)机制:索引被拆分为多个主分片(Primary Shard)和副本分片(Replica Shard),分片分布在集群的各个节点。
- 自动负载均衡:新增节点后,Elasticsearch 会自动将部分分片迁移到新节点,实现负载均衡。
- 无缝扩展:扩容过程对用户透明,无需停机或手动干预数据迁移。
2.2 水平扩容的典型场景
- 存储容量不足:原始节点磁盘空间不足,需增加节点扩展存储。
- 性能瓶颈:查询延迟高或写入吞吐量不足,需分散负载。
- 高可用性需求:通过更多节点提高副本分片数量,增强容错能力。
2.3 水平扩容的具体步骤
步骤 1:添加新节点到集群
- 配置新节点:
- 在新节点上安装 Elasticsearch,确保以下配置与现有集群一致:
# elasticsearch.yml cluster.name: my-cluster # 集群名称必须一致 discovery.seed_hosts: ["node1_ip:9300", "node2_ip:9300"] # 现有集群节点地址
- 若新节点是数据节点,确保 node.roles: [ data ](默认角色)。
- 若新节点是专用主节点或协调节点,需显式配置角色。
- 在新节点上安装 Elasticsearch,确保以下配置与现有集群一致:
- 启动新节点:
- 新节点会自动加入集群,并接收分片分配任务。
步骤 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" } } ] }
- 若需强制重新分配分片,使用 _cluster/reroute API:
2.4 扩容后的优化策略
-
分片设计优化
- 主分片数:
- 建议每个分片大小在 10GB-50GB 之间(避免过大导致迁移慢)。
- 主分片数应与数据增长预期匹配,通常可按 数据总量 / 30GB 估算。
- 副本分片数:
- 增加 number_of_replicas 可提高读取吞吐量和容错能力,但会占用更多存储。
- 主分片数:
-
跨节点负载均衡
- 分片分配过滤:
- 通过 awareness 配置实现跨机架或可用区(AZ)分布:
# elasticsearch.yml cluster.routing.allocation.awareness.attributes: rack # 按机架感知分配 node.attr.rack: rack1 # 节点所属机架
- 热冷分离架构:
- 使用 ILM(Index Lifecycle Management) 将冷数据迁移到低成本节点。
- 分片分配过滤:
2.5 水平扩容的注意事项
- 主分片数不可变:
- 索引的主分片数量在创建后无法修改,需提前规划或通过 Reindex API 重建索引。
- 网络与硬件一致性:
- 新节点的硬件配置(如磁盘类型、CPU)应与旧节点尽量一致,避免性能瓶颈。
- 脑裂风险:
- 扩容主节点时,确保 discovery.zen.minimum_master_nodes(7.x 之前版本)配置正确,防止多主节点冲突。
- 分片分布均匀性:
- 避免分片集中在少数节点,可通过 _cluster/allocation/explain 分析未分配分片的原因。