bigywater.tech
ZooKeeper · 43

ZAB 崩溃恢复流程

leader 崩溃的瞬间,有些写已经确认、有些还在路上。ZooKeeper 保证什么?这篇让一个线程持续写入、杀掉 leader 并核对每一个请求的结果,验证「已确认的写不丢」,并看看「没确认的」到底发生了什么。

0 个丢失
5 次崩溃共 5890 个已确认写入,全部保留
3 / 5
ConnectionLoss 的请求里,实际已经写入的数量
恢复后一致
三个节点 zxid 与 znode 总数相同

已确认的写入不丢

实测 · 本机执行输出
   次     已确认      确认后丢失    未确认(ConnectionLoss)        其中实际已写入
   1    1189          0                      1              1
   2    1031          0                      1              0
   3    1218          0                      1              1
   4    1251          0                      1              0
   5    1201          0                      1              1
  汇总:已确认的写全部保留 = True | 未确认的写里实际已经写入的合计 = 3 / 5

已确认 = 客户端的 create 调用返回成功。这个保证来自「只有多数派确认的提案才会被提交」加上选举规则(第 35 篇):新 leader 一定拥有所有已提交的事务。

恢复后的一致性

实测 · 本机执行输出
  三个节点的 zxid: {'z43-1': '0x6000003dd', 'z43-2': '0x6000003dd', 'z43-3': '0x6000003dd'} | 一致: True
  各节点上 /r0..r4 下的 znode 总数: {'z43-1': 5893, 'z43-2': 5893, 'z43-3': 5893} | 一致: True

分步演示

崩溃恢复
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。3 节点伪集群;写入线程是单个 kazoo 客户端的同步 create;每次杀当时的 leader 后等 6 秒再核对;共 5 次
    • 没有验证:多个客户端并发写、杀掉的是 follower 的情形、磁盘 fsync 关闭(forceSync=no)时的持久性、整个集群同时断电
    京ICP备2026067502号-1京公网安备11010502063487号