基于本文回答
0
评论

Elasticsearch 是如何进行选主节点(Master Election)的?

知识点图片

Elasticsearch 的选主(Master Election)机制在 7.x 版本前后发生了重大的变化。

简单来说:

  • 7.0 及以后:使用基于 Raft 的共识算法(Raft-inspired),更加严谨、安全,自动处理脑裂问题。
  • 7.0 以前:使用 Zen Discovery 模块,基于类似 Bully 算法的定制机制,需要手动配置 minimum_master_nodes 来防止脑裂。

以下是详细的流程解析,重点介绍目前主流的 7.x+ 版本机制。


一、 Elasticsearch 7.x 及更高版本(现代机制)

从 ES 7.0 开始,引入了新的集群协调子系统(Cluster Coordination),其选主算法深受 Raft 共识算法 的启发。

1. 核心概念

  • Master-eligible Node(候选主节点):配置了 node.master: true 的节点。只有这些节点有资格参与竞选和投票。
  • Voting Configuration(投票配置):这是 ES 7.x 动态维护的一组节点列表,只有在这个列表里的节点才有投票权。ES 会自动维护这个列表以确保集群的高可用性。
  • Quorum(法定人数/多数派):选主必须获得 Voting Configuration 中 超过半数 节点的投票。
  • Term(任期):一个递增的整数计数器。每次选举都会增加 Term,用于区分新旧 Master,防止僵尸节点(旧 Master)干扰集群。

2. 选主流程步骤

第一步:触发选举
当集群启动,或者当前的 Master 节点挂掉(其他节点在 cluster.fault_detection.leader_check 失败),或者当前 Master 主动辞职时,选举开始。

第二步:候选人(Candidate)发起竞选
某个 Master-eligible 节点发现没有 Master,它会:

  1. 将自己的 Term 加 1。
  2. 将自己转换为 Candidate 状态。
  3. 给自己投一票。
  4. 向其他 Master-eligible 节点发送 RequestVote 请求。

第三步:节点投票(Voting)
收到投票请求的节点会根据以下规则决定是否投票给该 Candidate:

  1. Term 检查:Candidate 的 Term 必须大于等于当前节点的 Term。
  2. 状态新鲜度:Candidate 拥有的 Cluster State(集群状态) 版本必须足够新(至少不落后于投票节点)。这保证了新 Master 拥有最新的元数据。
  3. 未重复投票:在当前 Term 内,投票节点还没有投给其他人。

第四步:当选(Winning)
如果 Candidate 收到了来自 Voting Configuration 中过半数 节点的投票,它就当选为 Master。

第五步:发布集群状态
新 Master 会发布一个新的 Cluster State,并向全集群广播。一旦该状态被多数派确认(Committed),选举正式完成,集群恢复服务。

3. 如何防止脑裂(Split Brain)?

在 7.x 中,你不再需要配置 minimum_master_nodes。ES 通过 Voting Configuration 自动管理多数派。如果集群分裂成两部分,只有包含“多数派”的那一部分能选出 Master,另一部分因为票数不足无法选主,从而自动进入阻塞状态,避免数据不一致。

注意:在 7.x 集群第一次启动时,必须在配置中设置 cluster.initial_master_nodes,明确指定哪些节点参与首次选举(Bootstrapping)。启动后该配置即可忽略。


二、 Elasticsearch 7.0 以前版本(Zen Discovery)

如果你还在维护 ES 5.x 或 6.x,机制完全不同。使用的是 Zen Discovery

1. 核心逻辑

它采用了一种类似 Bully 算法 的变体:

  1. 节点通过 Ping 发现彼此。
  2. 节点根据 Node ID 进行排序。
  3. 通常 ID 最小(或根据具体规则排序最优)的节点会被选为 Master。

2. 致命弱点与脑裂

旧版算法最大的问题是无法自动准确判断“多数派”。

  • 场景:假设有 3 个节点(A, B, C),网络断开,A 单独一组,B 和 C 一组。
  • 结果:A 觉得自己是 Master,B 和 C 选出 B 做 Master。此时集群有两个 Master,即“脑裂”。两个 Master 同时写入数据,导致数据损坏或丢失。

3. 解决方案

必须在 elasticsearch.yml 中手动硬编码配置:

yaml
discovery.zen.minimum_master_nodes: N/2 + 1

例如 3 个主节点,必须配置为 2。如果配置错误,极易发生数据事故。


三、 总结对比

特性 7.x 及以后 (Cluster Coordination) 7.0 以前 (Zen Discovery)
算法基础 Raft-inspired (强一致性共识) Bully 变体 (基于排序)
脑裂保护 自动 (通过 Voting Configuration) 手动 (需配置 minimum_master_nodes)
选主速度 非常快 (通常几秒内) 较慢 (Ping 周期可能较长)
首次启动 需配置 cluster.initial_master_nodes 自动发现
安全性 极高 (检查 Cluster State 新鲜度) 一般 (可能选出状态落后的节点)

结论

ES 的选主是为了维护 Cluster State(集群状态) 的唯一性和一致性。

  • 现代 ES 通过 Raft 机制,要求多数派同意数据最新的节点才能当选,从算法层面根除了脑裂问题。
  • 旧版 ES 依赖人为配置的数学公式来规避风险。
右滑查看面试常问