CodeWalk

ZooKeeper选举机制详解

作者:孤独的心 · 2026-05-30 12:55

请详细说明ZooKeeper的Leader选举过程,包括选举触发条件、选举算法(Fast Leader Election)以及投票规则。

回答

孤独的心

选举触发条件:

  1. 集群启动时首次选举
  2. Leader节点宕机或网络不可达
  3. 过半数Follower与Leader心跳超时(tickTime × syncLimit,默认10×5=50秒)

选举算法:Fast Leader Election(FLE,Zab协议实现)

选举过程:

Step 1 - 变更状态:

  • 所有Server进入LOOKING状态(开始选举)
  • 如果Leader宕机,Follower检测到超时后也进入LOOKING

Step 2 - 发起投票:

  • 每个Server广播投票(serverId, zxid, epoch)
  • 初始投票: 每个Server投票给自己(SID,ZXID)

Step 3 - 接收投票:

  • Server收到其他Server的投票后,进行PK规则
PK规则(优先级从高到低):
1. epoch(Leader任期):epoch大的获胜
2. zxid(事务ID):zxid大的获胜(数据更新)
3. serverId(服务器ID):serverId大的获胜

Step 4 - 更新投票:

  • 如果收到的投票比自己当前的投票更好(按PK规则),则更新自己的投票
  • 广播更新后的投票

Step 5 - 收集结果:

  • 当某个Server收到过半数相同的投票(即多数派同意同一个Leader)
  • 该Server切换为LEADING或FOLLOWING状态

选举示例(3节点:S1、S2、S3):

假设:S1(ZXID=100), S2(ZXID=99), S3(ZXID=100)

初始:S1投(S1,100), S2投(S2,99), S3投(S3,100)

S1收到S3的(S3,100):ZXID相同,S3的SID(3)>S1的SID(1) → S1改投S3
S3收到S1的(S1,100):ZXID相同,S3(3)>S1(1) → S3维持投自己
S2收到S3的(S3,100):ZXID更大 → S2改投S3

最终:S3获得3票(过半数)→ S3成为Leader

Observer角色:

  • Observer不参与选举,只同步数据
  • 用于扩展集群的读能力