bigywater.tech
ZooKeeper · 85

分布式配置中心

配置中心是 ZooKeeper 最经典的用途之一:配置写在节点里,应用 watch 它,改了立刻推送。这篇量推送有多快、连发更新会不会丢中间值、断网重连后看到什么,以及配置放一个节点还是拆成很多个节点的流量差别。

12.4 ms
50 个实例的推送延迟中位(p99 25.2 ms)
121–143 / 200
连发 200 次更新时各实例收到的回调数(最终值一致)
5526 vs 173 B
改 1 项:整份 JSON 与每项一个节点收到的字节

推送有多快

实测 · 本机执行输出
  50 个实例 × 30 次更新 = 1500 次推送:收到 1500,漏掉 0;延迟(ms)中位 12.4,p99 25.2,最大 26.0

延迟是在同一台机器上量的(客户端与 ZooKeeper 都在本机),只能说明服务端处理与一次 watch 通知的开销,不含跨机网络。

更新被合并

实测 · 本机执行输出
  200 次更新;各实例回调次数:最少 121,中位 134,最多 143;最终值都是 r199:True

watch 是一次性的:触发之后客户端要重新读并重新注册,这段时间里的更新只能看到最新的。kazoo 的 DataWatch 帮你自动重新注册,但合并依然存在。

断网重连

实测 · 本机执行输出
  断网期间该实例收到的回调: []
  恢复后 4.2 s 内收到: ['during-3'] (只有最新值 during-3,中间两次更新对它不可见)

重连成功后客户端把 watch 重新注册并带上自己见过的最后事务号,服务端发现数据已经变了就立即通知,所以不会一直拿着旧配置,但中间状态看不到。

冷启动

实测 · 本机执行输出
  连接 + 读取 = 13 ms,读到 during-3

一个节点还是多个节点

实测 · 本机执行输出
  整份 JSON(5400 字节):改 1 项后服务端发给该实例 5526 字节;每项一个节点(100 个节点):173 字节

配置越大、越新越频繁,拆分的收益越明显;但一次要改多个相关项时,拆开会遇到「读到半新半旧」的问题,见下一篇。

分步演示

配置推送
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。kazoo 2.11.0 的 DataWatch,50 个客户端在同一进程的不同连接上,服务端与客户端都在本机;断网用 TCP 代理关闭连接并拒绝重连
    • 没有验证:跨机房延迟、上千个实例同时订阅同一节点的推送延迟、配置大于 1 MiB(见第 1、22 篇)、权限控制(ACL)下的配置读取
    京ICP备2026067502号-1京公网安备11010502063487号