bigywater.tech
ZooKeeper · 57

磁盘满时的服务行为

ZooKeeper 的数据盘写满了会怎样?是只拒绝写,还是整个服务不可用?腾出一点空间就能恢复吗?这篇用一块只有 24 MiB 的磁盘映像把它们都试一遍。

节点自己退出
事务日志写失败后整个进程关闭,读也不可用
退出码 10
腾出 6 MiB 重启仍失败:启动时要写一份完整快照
数据不丢
搬到更大的盘后全部在

写到盘满

实测 · 本机执行输出
  起始可用空间 16.9 MiB
  成功写入 174 个(约 17.0 MiB)后第 175 次写入失败:ConnectionLoss;此时盘上可用 0.38 MiB
  进程还活着: False | 退出码: 0 | ruok: (ConnectionRefusedError)
  服务端日志里与磁盘满相关的行:
    [SyncThread:0] Severe unrecoverable error, from thread : SyncThread:0
    java.io.IOException: No space left on device
    [main] Shutting down
    [main] Shutting down
    [main] Shutting down
    [main] Shutting down

进程已经退出

实测 · 本机执行输出
  对 7300 端口发 ruok → ConnectionRefusedError

腾出空间重启

实测 · 本机执行输出
  腾出空间后可用 6.4 MiB
  重启失败(退出码 10);日志:
    [main] Severe unrecoverable error, exiting
    java.io.IOException: No space left on device
    [main] Exiting JVM with code 10
  数据目录里的快照文件(注意启动失败时留下了一个写了一半的快照): {'snapshot.0': '0.0 MiB', 'snapshot.af': '6.4 MiB'}

启动时写快照的行为在第 4 篇的日志里能看到(「Snapshot taken in … ms」)。恢复前先确认可用空间 > 当前数据的快照大小(第 53 篇)。

搬到更大的盘

实测 · 本机执行输出
  现在可用 6.4 MiB
  再次启动:失败(退出码 10)
  数据目录搬到 256 MiB 的盘上启动:成功;znode 数 180(写入成功的 174 个 100 KiB 的 znode 都在),并且可以继续写

分步演示

磁盘满
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。事务日志与快照放在 24 MiB 的 HFS+ 磁盘映像上,preAllocSize=512 KB;集群里单个节点盘满的情形没有测(其它节点会继续服务)
    • 没有验证:集群里一个节点盘满对整体的影响、dataLogDir 与 dataDir 分盘时只有一块盘满、监控磁盘使用率的告警阈值、Linux 上的错误码(本机是 macOS)
    京ICP备2026067502号-1京公网安备11010502063487号