bigywater.tech
ZooKeeper · 35

FastLeaderElection 消息流程

选 leader 看什么?sid 大的优先吗?这篇构造一个「sid 更大的节点数据落后」的场景,验证 FastLeaderElection 的选票比较规则;再看全新集群数据都一样时谁当选。

epoch > zxid > sid
选票的比较顺序
数据新者当选
sid 更大的落后节点落选
{2: 5}
全新集群 5 次启动的当选 sid 分布(启动顺序 1→2→3)

构造一个落后的候选者

实测 · 本机执行输出
  leader = z35-2(sid 2);follower:z35-1(sid 1)、z35-3(sid 3)
  停掉 sid 更大的 z35-3,再写 50 个 znode;然后杀掉 leader z35-2,重启 z35-3(它的 zxid 落后)
  新 leader = z35-1(sid 1);z35-1 的 zxid = 0x200000000、z35-3 的 zxid = 0x100000035
  → 有最新数据的 z35-1 当选,尽管 sid 更小
  落后节点的投票日志(它先投给自己,收到对方的更优选票后改投):
    09:48:12.044  新一轮选举:我(sid 3)提议 zxid=0x100000002
    09:48:12.046  收到 sid=3(LOOKING)的选票:选 sid=3,它的 zxid=0x100000002
    09:48:12.048  收到 sid=1(LOOKING)的选票:选 sid=1,它的 zxid=0x100000035
    09:48:12.048  收到 sid=1(LOOKING)的选票:选 sid=1,它的 zxid=0x100000035
    09:48:12.049  收到 sid=3(LOOKING)的选票:选 sid=1,它的 zxid=0x100000035

这样的规则保证:任何已经被多数派提交的事务,一定存在于新 leader 的日志里(多数派与多数派必有交集,而新 leader 是日志最新的)。这一段推理是对规则的解释,不是本实验直接测到的。

数据相同时

实测 · 本机执行输出
  5 次启动的 leader sid 分布: {2: 5} (数据相同时 sid 大的占优,但谁先凑够多数派取决于启动时机)

分步演示

选票比较
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。3 节点伪集群;落后的节点是 sid 较大的 follower,通过先停它再写 50 个 znode 制造;选票来自 INFO 日志的 Notification
    • 没有验证:五个节点以上的选举、网络延迟不对称时的选举、选举轮次 round 的完整语义、leader 选择与 observer(observer 不参与,第 28 篇)
    京ICP备2026067502号-1京公网安备11010502063487号