ZooKeeper 3.9.6 单机实测:单个 znode 上限约 1 MiB(1024 KiB 会 ConnectionLoss),同步写约 329 次/秒、同步读约 6361 次/秒,每个写都有全局递增的 zxid,整棵树常驻内存——小数据、强顺序、读多写少的协调服务。
单机、伪集群与集群的区别(ZooKeeper 3.9.6 实测):单机 Mode=standalone,写延迟 3.00 ms;3 节点伪集群 server.N + myid,写延迟 6.07 ms;只起 1/3 时进程在、ruok=imok 但不服务,起到 2/3 才能服务。
用 conf 命令看 zoo.cfg 的生效值:tickTime 默认 2000 ms,会话超时范围 [2×tick, 20×tick];客户端请求 60000 ms 被夹到 20000 ms;maxClientCnxns 连四字命令也算;拼错参数名(tickTim)静默忽略。
用启动日志还原 ZooKeeper 的启动流程:读配置 → 无 server.N 走单机分支 → 创建服务(带会话超时范围)→ 绑定端口 → 载入快照 → 启动请求处理链,整个日志内部约 90 ms;有数据重启多一步读快照;端口被占用时进程以退出码 1 退出。
ZooKeeper 数据目录实测:version-2 里是 log.<zxid> 事务日志(预分配 64 MiB,稀疏)和 snapshot.<zxid> 快照;每做一次快照事务日志就滚动;用 TxnLogToolkit 与 SnapshotFormatter 读出里面的内容;dataLogDir 可把事务日志放到另一块盘。
用官方 ZooKeeperMain 逐条执行 create / get -s / set / ls -R / delete / deleteall / set -v / create -e / -s 等命令,看真实输出和错误信息:非空节点不能 delete、版本不对拒绝更新、父节点不自动创建,CLI 退出后临时节点还在会话超时之前。
znode 的数据模型实测:stat 的 11 个字段,哪些操作改变哪些字段(set 改 mzxid/version,创建 / 删除子节点改 pzxid/cversion/numChildren,setACL 只改 aversion;改子节点数据不影响父节点);路径的合法与非法写法。
临时节点与持久节点实测:ephemeralOwner 等于会话 id;close() 后几毫秒内消失,进程被 kill -9 要等 6.7 秒的会话超时;服务端重启后同一会话的临时节点仍在;TTL 节点与容器节点需要 extendedTypesEnabled。
顺序节点实测:10 位十进制序号;按父节点各自计数,创建一次 +1、删除不归还、不等于 cversion;8 线程并发创建 400 个得到恰好 0..399;临时顺序节点是分布式锁与队列的基础,会话关闭后序号不连续但相对顺序不变。
内存里的 DataTree 实测:每个 znode 数据 200 字节,200006 个 znode 时 JVM 已用堆 108.5 MiB(约每个 0.52 KiB),读延迟约 0.02 ms;重启从快照重建整棵树 840 ms。
ZooKeeper 客户端连接流程实测(3 节点集群 + kazoo):连接串里的地址被随机挑选;握手确认会话 id(最高字节是服务端 myid)和协商后的超时;服务端被 kill 后客户端 SUSPENDED → 换节点 CONNECTED,会话不变;只写一个地址则无法转移。
会话机制实测:会话 id 最高字节是创建它的服务端 myid;空闲时每 timeout/3 一个 ping(6 s 超时空闲 12 s 共 6 个);leader 的 dump 按过期时间分桶;连在 follower 上的会话在 leader 的 zk_global_sessions 里可见。