bigywater.tech
ZooKeeper · 8

临时节点与持久节点

临时节点什么时候消失?客户端被杀、服务端重启、会话正常关闭,三种情形差别很大,也是做服务发现、分布式锁时最需要弄清的行为。这篇逐一量出来,最后看 TTL 节点与容器节点两种较新的节点类型。

4 ms vs 6.7 s
临时节点消失的时间:正常 close() vs 进程被 kill -9(会话超时 6 s)
ephemeralOwner = 会话 id
持久节点是 0x0;临时节点没有子节点
服务端重启不删
会话保存在快照 / 日志里,客户端在超时内重连,临时节点还在

stat 里的区别

实测 · 本机执行输出
  /persist  ephemeralOwner = 0x0
  /eph      ephemeralOwner = 0x1000bb81ee50000   创建者会话 id = 0x1000bb81ee50000   相等: True
  create /eph/child → NoChildrenForEphemeralsError

什么时候被删除

实测 · 本机执行输出
  close() 之后到节点消失:4 ms
  客户端进程被 kill -9 之后立即查询: eph-kill 还在
  从进程被杀到节点消失:6718 ms(会话超时 6000 ms)

这就是服务发现里「实例挂了多久会被摘除」的答案:取决于会话超时(第 13 篇),不是 TCP 断开的时间。

服务端重启

实测 · 本机执行输出
  服务端重启后 /eph-restart 还在: True | 同一个会话 id: True

TTL 节点与容器节点

实测 · 本机执行输出
  [zk] create -t 2000 /ttl1 x → Created /ttl1
  轮询看到 /ttl1 存在了 2029 ms(TTL = 2000 ms,容器检查间隔被我设成 300 ms)
  [zk] create -c /cont → Created /cont |  create -c /cont/child x → Created /cont/child
  容器节点 /cont 在删掉最后一个子节点 245 ms 后被自动删除
  没有 extendedTypesEnabled 的另一个节点上 create -t 1000 /x → KeeperErrorCode = Unimplemented for /x

这两种节点由服务端的 ContainerManager 定期清理,清理间隔默认 60 秒(本实验把它调成 300 ms 才能观察),所以实际的消失时间会比 TTL 长一个检查周期。

分步演示

临时节点的生命周期
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 / ZooKeeper 3.9.6(brew 安装的 jar,用 java -cp 直接启动自己的实例,OpenJDK 17 Temurin,JVM 堆 128 MiB)/ 本机回环端口 7300+,数据在临时目录;默认 tickTime=2000;计时用 time.perf_counter,数字每次运行会有小幅抖动。tickTime=1000;客户端 kazoo(请求的会话超时 6 s);TTL / 容器节点用官方 CLI 创建,JVM 加 -Dzookeeper.extendedTypesEnabled=true、-Dznode.container.checkIntervalMs=300
    • 没有验证:多服务端节点集群里重启 leader 对临时节点的影响(第 36 篇)、会话迁移、容器检查间隔的默认值 60 s 下的实际延迟(只看到日志里写着 checkIntervalMs=60000)、kazoo 的会话重连策略
    京ICP备2026067502号-1京公网安备11010502063487号