bigywater.tech
ZooKeeper · 27

集群角色与请求路径

ZooKeeper 集群里的 leader 和 follower 各做什么?写和读分别走哪条路?这篇在 3 节点集群上用 mntr 和包计数把请求路径量出来。

写 → leader
不管连在哪个节点,写事务都由 leader 排序
+1 个包
连在 follower 读 2000 次,leader 多收到的包数
zxid 一致
写完之后三个节点的 Zxid 相同

三个角色的差别

实测 · 本机执行输出
  z27-1 follower  zk_server_state=follower  zk_followers=None  zk_synced_followers=None  zk_learners=None
  z27-2 leader    zk_server_state=leader  zk_followers=None  zk_synced_followers=2  zk_learners=2
  z27-3 follower  zk_server_state=follower  zk_followers=None  zk_synced_followers=None  zk_learners=None

写的路径

实测 · 本机执行输出
  连 leader:5.90 ms;连 follower:5.03 ms(follower 要多转发一跳,但差别被 fsync 的耗时淹没)

这个测量里连 follower 的结果甚至略快,属于测量噪声(单机五个 JVM 抢同一块磁盘与 CPU),所以结论只能是「没有可见的差别」。

读的路径

实测 · 本机执行输出
  连 follower 读 2000 次:leader 收到包 +1;连 leader 读 2000 次:leader 收到包 +2001

结果一致

实测 · 本机执行输出
  各节点 Zxid: {'z27-1': '0x100000263', 'z27-2': '0x100000263', 'z27-3': '0x100000263'}

分步演示

集群角色
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。3 节点伪集群;延迟是 300 次同步 create 的中位数
    • 没有验证:follower 读到旧数据的概率(第 44 篇试了一个测法,没有观察到)、跨机房的转发延迟、observer 的路径(第 28、29 篇)、写请求转发的内部协议
    京ICP备2026067502号-1京公网安备11010502063487号