一、客户端连接ZooKeeper服务器
1.1 启动ZooKeeper集群
在操作客户端之前,确保ZooKeeper集群已经正常启动:
# 启动ZooKeeper服务(所有节点都要执行)./zkServer.sh start# 查看服务状态./zkServer.sh status1.2 启动客户端连接本地服务器
./zkCli.sh启动后可以看到如下提示,表示已成功连接本地ZooKeeper服务器(默认端口2181):
[zk: localhost:2181(CONNECTED) 0]客户端启动时默认连接本地模式,这是因为zkCli.sh脚本中默认配置了localhost:2181。
1.3 指定连接集群中的特定服务器
在实际生产环境中,我们通常需要连接集群中的指定节点进行调试或管理:
# 连接hadoop102节点./zkCli.sh-serverhadoop102:2181# 也可以从一台服务器连接另一台服务器# 例如在hadoop102上连接hadoop103./zkCli.sh-serverhadoop103:2181连接成功后提示变为:
[zk: hadoop103:2181(CONNECTED) 0]二、常用命令速查表
| 命令 | 语法 | 功能说明 |
|---|---|---|
help | help | 显示所有操作命令 |
ls | ls path | 查看指定路径下的子节点 |
ls -s | ls -s path | 查看子节点及当前节点状态信息 |
create | create path data | 创建持久化节点 |
create -s | create -s path data | 创建持久顺序节点 |
create -e | create -e path data | 创建临时节点 |
create -e -s | create -e -s path data | 创建临时顺序节点 |
get | get path | 获取节点数据 |
get -s | get -s path | 获取节点数据及状态信息 |
set | set path data | 修改节点数据 |
delete | delete path | 删除单个节点(无子节点) |
deleteall | deleteall path | 递归删除节点及其子节点 |
stat | stat path | 查看节点状态信息 |
get -w | get -w path | 监听节点数据变化(一次性) |
ls -w | ls -w path | 监听子节点数量变化(一次性) |
三、节点信息详解
3.1 查看当前Znode包含的内容
[zk: hadoop102:2181(CONNECTED)0]ls/[zookeeper]刚安装的ZooKeeper默认只有一个zookeeper节点,用于存储ZooKeeper自身的配置信息。
3.2 查看当前节点的详细信息
[zk: hadoop102:2181(CONNECTED)2]ls-s/[zookeeper]cZxid=0x0 ctime=Thu Jan 01 08:00:00 CST1970mZxid=0x0 mtime=Thu Jan 01 08:00:00 CST1970pZxid=0x0 cversion=-1dataVersion=0aclVersion=0ephemeralOwner=0x0 dataLength=0numChildren=13.3 节点状态参数解读
| 参数 | 说明 |
|---|---|
| czxid | 创建节点的事务ID。每次修改ZooKeeper状态都会产生一个唯一的事务ID,zxid越小表示操作越早发生 |
| ctime | znode被创建的毫秒数(从1970年开始计算) |
| mzxid | znode最后更新的事务ID |
| mtime | znode最后修改的毫秒数(从1970年开始计算) |
| pZxid | znode最后更新的子节点的zxid |
| cversion | znode子节点变化号,记录子节点修改次数 |
| dataVersion | znode数据变化号,每次修改数据都会递增 |
| aclVersion | znode访问控制列表的变化号 |
| ephemeralOwner | 如果是临时节点,值为znode拥有者的session id;持久节点则为0 |
| dataLength | znode的数据长度(字节数) |
| numChildren | znode当前子节点数量 |
四、节点类型详解
ZooKeeper中的节点(Znode)分为两大类:持久节点和临时节点,每种类型又可以分为有序号和无序号两种。
4.1 持久节点(Persistent)
客户端与ZooKeeper服务器断开连接后,创建的节点不会删除。
4.1.1 持久化目录节点(不带序号)
# 创建节点时必须赋值[zk: hadoop102:2181(CONNECTED)4]create /sanguo"diaochan"Created /sanguo# 查看根目录[zk: hadoop102:2181(CONNECTED)5]ls/[sanguo, zookeeper]# 创建子节点[zk: hadoop102:2181(CONNECTED)6]create /sanguo/shuguo"liubei"Created /sanguo/shuguo[zk: hadoop102:2181(CONNECTED)7]ls/sanguo[shuguo]4.1.2 持久化顺序编号目录节点(带序号)
创建znode时设置顺序标识,znode名称后会附加一个单调递增的序号,由父节点维护。
# 先创建父节点[zk: hadoop102:2181(CONNECTED)10]create /sanguo/weiguo"caocao"Created /sanguo/weiguo# 创建带序号的子节点[zk: hadoop102:2181(CONNECTED)12]create-s/sanguo/weiguo/zhangliao"zhangliao"Created /sanguo/weiguo/zhangliao0000000000# 再次创建同名节点,序号自动递增[zk: hadoop102:2181(CONNECTED)13]create-s/sanguo/weiguo/zhangliao"zhangliao"Created /sanguo/weiguo/zhangliao0000000001# 创建另一个带序号节点[zk: hadoop102:2181(CONNECTED)14]create-s/sanguo/weiguo/simayi"simayi"Created /sanguo/weiguo/simayi0000000002# 查看结果[zk: hadoop102:2181(CONNECTED)15]ls/sanguo/weiguo[simayi0000000002, zhangliao0000000000, zhangliao0000000001]顺序号的应用场景:在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,客户端可以通过顺序号推断事件的先后顺序。
4.2 临时节点(Ephemeral)
客户端与ZooKeeper服务器断开连接后,创建的节点自动删除。
4.2.1 临时目录节点(不带序号)
[zk: hadoop102:2181(CONNECTED)16]create-e/sanguo/wuguo"sunquan"Created /sanguo/wuguo# 当前客户端可以查看到[zk: hadoop102:2181(CONNECTED)17]ls/sanguo[shuguo, weiguo, wuguo]# 退出当前客户端[zk: hadoop102:2181(CONNECTED)18]quit# 重新连接后查看,临时节点已消失[zk: hadoop102:2181(CONNECTED)0]ls/sanguo[shuguo, weiguo]4.2.2 临时顺序编号目录节点(带序号)
[zk: hadoop102:2181(CONNECTED)19]create-e-s/sanguo/wuguo"sunquan"Created /sanguo/wuguo00000000004.3 四种节点类型对比
| 节点类型 | 断开连接后 | 是否有序号 | 典型应用场景 |
|---|---|---|---|
| 持久无序号 | 保留 | 否 | 配置信息存储 |
| 持久有序号 | 保留 | 是 | 分布式队列、全局ID生成 |
| 临时无序号 | 删除 | 否 | 服务注册与发现 |
| 临时有序号 | 删除 | 是 | 分布式锁、Leader选举 |
五、节点数据操作
5.1 获取节点数据
# 获取节点数据及状态[zk: hadoop102:2181(CONNECTED)9]get-s/sanguo diaochan cZxid=0x40000000c ctime=Tue Jun1318:31:38 CST2023mZxid=0x40000000c mtime=Tue Jun1318:31:38 CST2023pZxid=0x40000000d cversion=1dataVersion=0aclVersion=0ephemeralOwner=0x0 dataLength=8numChildren=15.2 修改节点数据
# 修改前[zk: hadoop102:2181(CONNECTED)4]get-s/sanguo/weiguo caocao... dataVersion=0# 执行修改[zk: hadoop102:2181(CONNECTED)5]set/sanguo/weiguo"simayi"# 修改后[zk: hadoop102:2181(CONNECTED)6]get-s/sanguo/weiguo simayi... dataVersion=1注意:
dataVersion从0变为1,每次修改都会递增,这是乐观锁机制的基础。
六、监听器机制(Watch)
ZooKeeper的Watch机制是实现分布式协调的核心特性。客户端可以向服务器注册监听,当监听的事件发生时,服务器会主动通知客户端。
6.1 Watch的重要特性
- 一次性触发:注册一次监听只能监听一次变化,事件触发后监听自动失效
- 轻量级:客户端只接收通知,不接收具体变更数据,需要客户端主动拉取
- 实时性:数据变更后,服务器会立即推送通知
6.2 监听节点数据变化
在hadoop104上注册监听,在hadoop102上修改数据:
# 【hadoop104】注册数据变化监听[zk: hadoop104:2181(CONNECTED)1]get-w/sanguo diaochan# 【hadoop102】修改节点数据[zk: hadoop102:2181(CONNECTED)2]set/sanguo"lvbu"# 【hadoop104】收到通知WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo再次修改
/sanguo的数据,hadoop104不会再收到通知,需要重新注册监听。
6.3 监听子节点数量变化
# 【hadoop104】注册子节点变化监听[zk: hadoop104:2181(CONNECTED)0]ls-w/sanguo[shuguo, weiguo]# 【hadoop102】新增子节点[zk: hadoop102:2181(CONNECTED)3]create /sanguo/dongwu"dongzhuo"Created /sanguo/dongwu# 【hadoop104】收到通知WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo6.4 两种监听方式对比
| 监听类型 | 命令 | 触发条件 | 事件类型 |
|---|---|---|---|
| 数据变化监听 | get -w path | 节点数据被修改 | NodeDataChanged |
| 子节点变化监听 | ls -w path | 子节点增删 | NodeChildrenChanged |
七、节点删除操作
7.1 删除单个节点
只能删除没有子节点的节点:
[zk: hadoop102:2181(CONNECTED)13]ls/[sanguo, wuguo, zookeeper][zk: hadoop102:2181(CONNECTED)14]delete /wuguo[zk: hadoop102:2181(CONNECTED)15]ls/[sanguo, zookeeper]如果节点有子节点,会报错:
Node not empty: /sanguo
7.2 递归删除节点
删除节点及其所有子节点:
[zk: hadoop102:2181(CONNECTED)15]ls/[sanguo, zookeeper][zk: hadoop102:2181(CONNECTED)16]deleteall /sanguo[zk: hadoop102:2181(CONNECTED)17]ls/[zookeeper]7.3 查看节点状态
stat命令查看节点状态,不显示节点数据:
[zk: hadoop102:2181(CONNECTED)18]stat/zookeeper cZxid=0x0 ctime=Thu Jan 01 08:00:00 CST1970mZxid=0x0 mtime=Thu Jan 01 08:00:00 CST1970pZxid=0x0 cversion=-1dataVersion=0aclVersion=0ephemeralOwner=0x0 dataLength=0numChildren=1
stat与get -s的区别:get -s会多输出一行节点数据内容。
八、实战技巧与常见问题
8.1 快速清空所有测试数据
# 查看所有节点ls/# 递归删除(保留zookeeper系统节点)deleteall /sanguo deleteall /weiguo8.2 常见问题排查
| 问题 | 原因 | 解决方案 |
|---|---|---|
Node not empty | 节点有子节点 | 先删除子节点,或使用deleteall |
NoNode for /xxx | 节点不存在 | 检查路径是否正确 |
NotEmptyException | 同上 | 同上 |
| 监听不触发 | Watch是一次性的 | 事件触发后需要重新注册 |
| 临时节点未删除 | 会话未断开 | 检查客户端是否真正退出 |
8.3 命令执行流程图
连接服务器 → 查看节点(ls) → 创建节点(create) → 获取数据(get) ↓ ↓ ↓ 监听节点(ls -w) 带序号(-s) 修改数据(set) ↓ ↓ ↓ 收到通知 临时节点(-e) 删除节点(delete) ↓ ↓ ↓ 重新注册监听 自动清理 递归删除(deleteall)九、总结
ZooKeeper的命令行操作虽然简单,但每个命令背后都蕴含着分布式系统设计的深刻思想:
- 持久/临时节点→ 服务持久化 vs 会话绑定
- 顺序编号→ 全局有序性保证
- Watch机制→ 发布订阅模式的实现
- 版本号→ 乐观锁并发控制
掌握这些基础命令,是理解ZooKeeper在Hadoop、Kafka、HBase等生态系统中发挥协调作用的必经之路。