ZooKeeper选举Leader过程

wen java案例 2

本文目录导读:

ZooKeeper选举Leader过程

  1. 选举触发条件
  2. 核心选举依据:事务 ID (ZXID) 和服务器 ID (myid)
  3. 选举过程详解(以 5 台机器为例,初始启动)
  4. 特殊情况处理
  5. 关键概念总结
  6. 总结流程图

ZooKeeper 的 Leader 选举过程是其核心机制,用于在集群中选出一个 Leader 节点来负责处理写请求和事务,Follower 节点则负责处理读请求和投票,选举主要在 服务器启动阶段Leader 故障/失联 时触发。

ZooKeeper 默认使用 FastLeaderElection 算法(基于 Paxos 和 Zab 协议),以下是选举过程的详细分解:

选举触发条件

  • 服务器启动时:所有节点均处于 Looking 状态(选举中),需要选出一个 Leader。
  • Leader 崩溃或网络隔离:当前 Leader 无法与集群中超过半数的节点保持连接,导致集群进入 Looking 状态。

核心选举依据:事务 ID (ZXID) 和服务器 ID (myid)

选举的关键是投票给哪个节点,比较的优先级如下:

  1. 比较 ZXID:最后处理的 事务 ID(zxid 是一个 64 位数字,高 32 位为 epoch(纪元),低 32 位为计数),ZXID 越大,表示数据越新。
  2. 比较 myid:ZXID 相同,则比较 服务器 ID(在 myid 文件中配置的整数,如 1, 2, 3),myid 越大,优先级越高。

选举结果:ZooKeeper 会选择 ZXID 最大myid 最大 的那个节点作为 Leader(因为 ZXID 大的节点拥有最新的数据,可以保证一致性)。

选举过程详解(以 5 台机器为例,初始启动)

发起投票

  • 所有节点都认为自己没有投票,因此每一台服务器都会投自己一票。
  • 初始投票信息:(myid, ZXID),如果数据完全一致,所有服务器都会推荐自己。

接收并比较投票

  • 每台服务器将投票发给集群中的其他所有服务器。

  • 当服务器 B 收到服务器 A 的投票 (myid_A, ZXID_A) 时,B 会将其与自己的投票 (myid_B, ZXID_B) 进行对比:

    • 规则:先比较 ZXID,选大的;ZXID 相同,再比较 myid,选大的。
    • A 的优先级更高:B 会改变自己的投票,转而投给 A(即更新自己的投票为 (myid_A, ZXID_A)),并且把这个更新后的投票重新广播给所有节点。
    • B 的优先级更高:B 维持原投票,并继续广播。

统计票数,确定 Leader

  • 每台服务器不断接收和比较投票,并更新自己的投票。
  • 一个节点会统计收到的所有投票(包括自己的),当 某台服务器(比如节点 A)得到的票数超过集群总节点数的一半(即 > n/2 时,该服务器 A 就成为 Leader。
    • 例如:5 台节点,A 得到 3 票(包括自己),则 A 胜出。
    • 重要:这个准则是过半原则,ZooKeeper 集群必须包含奇数台节点(如 3, 5, 7)以避免平局。

改变状态

  • 赢得投票的节点:状态从 LOOKING 变为 LEADING,成为 Leader。
  • 其他节点:状态从 LOOKING 变为 FOLLOWING,成为 Follower。
  • Leader 会向所有 Follower 发送一个 NewLeader 通知,Follower 确认后,Leader 会发送 Uptodate 确认,至此,集群进入正常工作状态。

特殊情况处理

Leader 故障后的快速重新选举

  • 假设当前 Leader 是节点 3(myid=3, ZXID 较大),当它宕机后:
    • 剩余节点(如 1, 2, 4, 5)检测到 Leader 失去连接,进入 LOOKING 状态。
    • 它们之间互相投票,由于节点 5 拥有仅次于 Leader 3 的最大 ZXID(或许它与 3 同步了最新数据),它会获得大部分票。
    • 节点 5 成为新 Leader,这个过程通常很快,因为数据差距不大。

Leader 被孤立(脑裂防止)

  • ZooKeeper 不允许“脑裂”(两个 Leader 同时存在),因为 Leader 只有在接收到超过半数节点的支持时才能继续当 Leader。
  • 假设集群为 5 台机器,Leader 1 与 Follower 2,3 在一个分区,Follower 4,5 在另一个分区。
    • 分区 1:Leader 1、F2、F3 可以互相通信(3 台,过半)。
    • 分区 2:F4、F5 只能互相通信(2 台,不足过半)。
    • 规则:分区 2 中的 F4 和 F5 无法选举出 Leader,因为它们各自只能得到 2 票(未过半数),所以它们一直处于 LOOKING 状态,不会产生新 Leader,分区 1 仍可正常服务。
    • 这保证了只有拥有多数节点的分区才能产生 Leader,避免了数据不一致。

关键概念总结

术语 含义 作用
myid 服务器唯一 ID (整数) 写死在 data/myid 文件中,用于在 ZXID 相同时决定谁更优先
ZXID 事务 ID 64 位整数,高 32 位是纪元(epoch),低 32 位是计数,代表了数据的新旧程度
epoch 时代/纪元 每次新 Leader 选出,epoch 都会加 1,用于隔离历史 Leader 发出的过时投票
Quorum(法定人数) 过半数 > n/2,选举和提交事务都必须达到该数量,防止脑裂和数据丢失
Looking 选举中状态 只有处于该状态的节点才会参与投票

总结流程图

集群剩余 / 启动
    |
    所有节点:LOOKING
    |
    1. 投给自己:发送 (myid, ZXID)
    |
    2. 收到别人投票 -> 比较 (ZXID > or myid >)
    |   |
    |   +---- 别人大:更改投票为他,继续广播
    |   +---- 自己大:维持原票
    |
    3. 统计:某个节点得票数 > 总节点数/2
    |
    +---- 是:该节点成为 LEADING (Leader),其他变为 FOLLOWING
    |
    +---- 否:继续循环,直到选出 Leader 或超时

抱歉,评论功能暂时关闭!