Elasticsearch 的 Master 节点选举通过 Zen Discovery 模块实现(7.x 版本后逐步整合为更现代化的集群协调机制,但核心逻辑相似),其选举算法基于 类 Bully 算法。以下是核心流程和关键设计:
选举核心流程
-
节点角色识别
- 只有配置了
node.roles: [ master ]
的节点(或旧版的node.master: true
)才有资格参与选举。
- 只有配置了
-
选举触发条件
- 集群启动时。
- 现有 Master 节点失效(心跳超时、宕机、网络分区)。
- 现有 Master 节点主动离开集群。
-
选举过程(类 Bully 算法)
- 步骤1(探测阶段):每个候选节点向集群其他节点发送探测请求,收集所有可达的 Master 候选节点列表。
- 步骤2(排序比较) :根据节点ID(默认是启动时生成的唯一 UUID)进行字典序排序 (如
node-1
<node-2
),数值最小的节点胜出。 - 步骤3(投票与宣告) :
- 胜出节点向其他节点发送
VoteRequest
请求投票。 - 其他节点响应
VoteResponse
确认(需收到过半投票)。 - 胜出节点广播
StartAsMasterRequest
宣告成为新 Master。
- 胜出节点向其他节点发送
-
法定人数(Quorum)要求
- 选举成功需获得 多数票(Majority) ,即
(master_eligible_nodes / 2) + 1
。例如:- 3 个 Master 节点 → 至少需要 2 票。
- 5 个 Master 节点 → 至少需要 3 票。
- 避免脑裂(Split-Brain)的关键设计。
- 选举成功需获得 多数票(Majority) ,即
关键优化与机制
-
故障检测(Zen-FD)
- 节点间通过周期性
ping
检测存活。 - 若 Master 节点失联,其他节点会触发新一轮选举。
- 节点间通过周期性
-
最小 Master 节点数(
discovery.zen.minimum_master_nodes
)- 7.x 之前 :必须手动配置该值(如
2
),确保集群分区时仅多数侧能选举出新 Master。 - 7.x+ 版本 :由集群自动计算并维护(通过
cluster.initial_master_nodes
初始化)。
- 7.x 之前 :必须手动配置该值(如
-
引导集群(7.x+ 的
cluster.initial_master_nodes
)-
首次启动集群时,需显式声明初始 Master 候选节点列表:
yamlcluster.initial_master_nodes: ["node-1", "node-2", "node-3"]
-
确保集群在初始状态形成法定人数。
-
-
选举安全性
- 每个节点仅对同一任期(Term) 投一次票。
- 新 Master 需提交状态到多数节点,确保数据一致性。
脑裂(Split-Brain)防护
- 场景:网络分区导致集群分裂为两组。
- 防护机制 :
- 法定人数约束:仅获得多数票的分区能选举出有效 Master。
- 主节点主动退出:少数分区中的原 Master 节点自动降级。
- 数据写入保护:客户端写入仅由合法 Master 分区处理。
版本演进注意
- 6.x 及之前 :依赖
discovery.zen.minimum_master_nodes
手动配置。 - 7.0+ :
- 引入 集群引导服务(Cluster Bootstrapping) 替代手动配置。
- 逐步迁移到 Raft 风格选举(在部分协调功能中应用,如安全配置变更)。
示例:5节点集群选举
- Master 节点列表:
[node-A, node-B, node-C, node-D, node-E]
(ID 按字典序排序)。 - 若
node-A
宕机 → 剩余节点发起选举。 node-B
(ID最小)发起投票 → 获得node-C/D/E
的投票(共4票 > 3的半数)。node-B
成为新 Master。
最佳实践
- 奇数 Master 节点数:如 3 或 5,提高容错性。
- 专用 Master 节点:分离 Master 与 Data 角色,避免资源竞争。
- 避免频繁选举 :合理调参
discovery.zen.ping_timeout
(默认 3s)。
⚠️ 注意 :7.x 后部分配置项已废弃(如
discovery.zen.*
),改用cluster.initial_master_nodes
和内置选举优化。详细配置需参考对应版本官方文档。
这一设计确保了 Elasticsearch 集群的高可用性与数据一致性。