本文是大数据系列第 28 篇,详细介绍 ZooKeeper 的 ZNode 节点类型、内部数据结构、ZXID 事务 ID,以及 Watcher 监听机制的核心原理。

完整图文版(含截图):CSDN 原文 | 掘金

ZNode:ZooKeeper 的数据单元

ZooKeeper 以类 Unix 文件系统的树形结构组织数据,每个节点称为 ZNode。路径以 / 分隔,根节点为 /,例如 /app/config/db-host

ZNode 内部结构

每个 ZNode 同时存储数据元数据

字段说明
data字节数组,最大约 1 MB
dataVersion数据版本号,每次 setData 后自增
cversion子节点版本号,子节点增删后自增
aclVersionACL 权限版本号
ctime节点创建时间戳
mtime节点最后修改时间戳
ephemeralOwner临时节点所属 Session ID;持久节点此字段为 0
numChildren子节点数量

ZNode 设计用于存储元数据和配置信息,不适合存储大业务数据

ZNode 四种类型

1. 持久节点(Persistent)

创建后永久存在,直到显式删除。适合存储配置、服务元数据等需要长期保留的信息。

create /app/config "prod"

2. 持久顺序节点(Persistent Sequential)

自动在路径末尾追加 10 位递增序号,序号全局单调递增。

create -s /jobs/task "payload"
# 实际创建:/jobs/task0000000001
# 再次创建:/jobs/task0000000002

适用场景:分布式队列、有序任务分配。

3. 临时节点(Ephemeral)

与客户端 Session 生命周期绑定:Session 断开(超时或主动关闭)后,节点自动删除。临时节点不能有子节点

create -e /services/instance-a "192.168.1.10:8080"

适用场景:服务注册(下线自动注销)、心跳检测。

4. 临时顺序节点(Ephemeral Sequential)

同时具备”自动删除”和”全局有序”特性,是实现公平分布式锁Leader 选举的核心原语。

create -e -s /lock/node "client-1"
# 实际创建:/lock/node0000000001

竞争锁时,序号最小的节点持有锁;锁持有者断开后,下一个序号的节点收到通知并获取锁。

ZXID:事务 ID

ZooKeeper 为每个写操作分配全局唯一的 64 位事务 ID(ZXID):

| 高 32 位(epoch)| 低 32 位(counter)|
  • epoch(纪元):每次 Leader 选举后自增,标识当前 Leader 任期
  • counter(计数器):当前 Leader 任期内的事务序号,每次写操作自增
  • 全局单调递增:不同 epoch 之间通过高位保证总体有序

ZXID 的作用:

  1. ZAB 协议一致性:Follower 通过比较 ZXID 决定是否接受 Leader 的事务提案
  2. 崩溃恢复:节点重启后,通过比较 ZXID 从 Leader 同步缺失的事务
  3. 顺序保证:客户端请求按 ZXID 顺序执行,保障顺序一致性

Watcher 监听机制

Watcher 是 ZooKeeper 提供的事件驱动通知机制,允许客户端监听 ZNode 的变化。

核心特性

特性说明
一次性触发Watcher 触发一次后自动失效,需重新注册
异步通知通知不阻塞客户端正常操作
轻量级通知内容只包含事件类型和节点路径,不含完整数据
有序性同一客户端的事件通知按顺序到达

注册方式

# 注册数据监听
get -w /app/config

# 注册子节点监听
ls -w /services

触发事件类型

事件触发条件
NodeCreated被监听的节点被创建
NodeDeleted被监听的节点被删除
NodeDataChanged节点数据被修改(setData
NodeChildrenChanged节点的子节点列表变化

实践演示

在一个终端中注册监听并等待:

zkCli.sh -server h121.wzk.icu:2181

# 在根节点写入数据,同时注册 Watcher
get -w /

在另一个终端修改数据:

zkCli.sh -server h122.wzk.icu:2181
set / wzk.icu

第一个终端会立即收到通知:

WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged path:/

跨节点同步验证:数据写入任意节点后,其他所有节点立即可读到最新值,验证 ZAB 协议的强一致性。

Watcher 使用注意事项

  1. 必须重新注册:每次收到通知后,如果仍需监听,需立即调用 getData/getChildren/exists 重新注册
  2. 通知可能丢失:在重新注册之前的变化不会触发通知,高频变更场景需结合轮询
  3. 轻量设计:通知不携带变更后的数据,客户端收到通知后需主动查询最新数据

小结

ZNode 的四种类型(持久/持久顺序/临时/临时顺序)构成了 ZooKeeper 所有高级特性的基础原语。ZXID 保障了全局写操作的顺序性,Watcher 一次性触发机制在低开销下实现了分布式事件通知。下一篇将通过命令行实践深入演示 Watcher 的注册与触发过程。