ZooKeeper 把整棵树放在内存里,这是它读得快、也是它不适合存大量数据的原因。这篇创建到 20 万个 znode,量 JVM 堆和进程内存是怎么随 znode 数增长的、读延迟是多少、重启把树读回内存要多久。
znode 数 近似数据大小 JVM 已用堆 进程 RSS
6 0.0 MiB 6.0 MiB 87 MiB
10006 2.0 MiB 11.5 MiB 106 MiB
50006 10.0 MiB 32.4 MiB 160 MiB
100006 20.0 MiB 58.4 MiB 209 MiB
200006 40.1 MiB 108.5 MiB 257 MiBmntr 的 zk_approximate_data_size 只估算了路径和数据的大小(约 40 MiB),真正的 JVM 堆占用大得多,因为每个 znode 还有对象头、stat 结构、父子关系等开销。容量规划(第 60 篇)要用实测的堆占用,不是数据大小。(这里的「已用堆」每次都先手动触发了一次 GC;JVM 堆上限我设成 256 MiB。)
srvr 的 Latency min/avg/max(毫秒): 0/0.0192/1
停机时 data/version-2 里快照文件总大小 50.9 MiB,事务日志实际占盘 58.6 MiB(没有触发快照时数据主要在事务日志里) 日志: Reading snapshot …/snapshot.2d8eb 日志: Snapshot loaded in 412 ms, highest zxid is 0x30d43, digest is 428321081763740 日志: Snapshot taken in 134 ms 重启到能响应 840 ms;重启后 znode 数 200006
数据越多,重启越慢,选举后 follower 同步(第 42 篇)也越慢。快照加载日志里的耗时就是把树读回内存的时间。