bigywater.tech
ZooKeeper · 53

快照机制

快照是 ZooKeeper 持久化的第二条腿(第一条是事务日志)。它什么时候做、要多久、多大、会不会拖慢写?这篇逐项量出来,还试了快照压缩。

504~963
snapCount=1000 时相邻快照间隔的事务数(随机)
163 ms / 54 MiB
20 万 znode 写一份快照的耗时与大小
26 倍
gz 压缩后快照缩小的倍数(这份高度可压缩的数据)

什么时候做快照

实测 · 本机执行输出
  共 18 个快照;相邻间隔(事务数):[548, 859, 552, 641, 504, 595, 711, 932, 537, 727, 924, 820, 583, 963, 547, 680, 512]
  最小 504 / 最大 963(都落在 snapCount/2 = 500 到 snapCount = 1000 之间:True)

耗时与大小

实测 · 本机执行输出
    znode 数       快照文件    耗时 ms    文件 MiB
      10000 snapshot.2712       14       2.7
      50000 snapshot.c352       49      13.5
     200000 snapshot.30d42      163      54.1

耗时是启动时写新快照的日志耗时(「Snapshot taken in X ms」),单线程写一份完整的树。

不阻塞写

实测 · 本机执行输出
  触发快照(8 次):前台同步写 p50 3.76 ms / p99 11.72 ms / 最大 67.6 ms;不触发快照:p50 3.35 / p99 11.69 / 最大 85.0 ms

前台与后台测的是同一个节点;两种情形下后台都在持续写,所以延迟分布的差别只来自快照本身。

压缩

实测 · 本机执行输出
  压缩方式 默认(CHECKED)    文件 snapshot.186a2     27.0 MiB  写快照 176 ms
  压缩方式 gz             文件 snapshot.186a2.gz    1.1 MiB  写快照 653 ms

压缩换来更小的磁盘占用和更快的网络传输(SNAP 同步时),代价是写快照时更多 CPU 与时间。

分步演示

快照
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。单机;数据 200 字节;耗时来自日志;前台延迟是 12 秒内的同步写分布
    • 没有验证:快照 snappy 压缩(需要额外 jar)、集群里快照对 follower 同步的影响、很大的树(千万级 znode)上的快照耗时、磁盘较慢时快照对写入的影响
    京ICP备2026067502号-1京公网安备11010502063487号