Zookeeper 的安装及使用

摘要

  • 本文介绍 CentOS9 中 Zookeeper 的安装与使用。

  • Zookeeper官网

  • 本文使用的 Zookeeper 版本为 3.8.4。

Zookeeper 简介

  • ZooKeeper 是一个集中式服务,用于:

场景 ZooKeeper 官方功能 主要节点类型 具体场景示例
配置中心 (Config Center) 维护配置信息 (Configuration Management) 持久节点(Persistent) 把数据库连接信息、系统参数等放在 ZooKeeper 里,动态更新,像 Apollo、Spring Cloud Config 一样。
注册中心 (Service Registry) 提供命名服务 (Naming Service) 临时节点(Ephemeral) 服务实例启动时在 ZooKeeper 里注册自己的地址,客户端从 ZooKeeper 获取服务列表,类似于 Nacos、Eureka。
分布式锁 (Distributed Lock) 分布式同步 (Distributed Synchronization) 临时顺序节点(Ephemeral Sequential) 用临时顺序节点实现分布式锁,保证只有一个实例在执行关键任务,典型应用是分布式定时任务调度。
消息队列 (Message Queue) 集群管理服务 (Cluster Management) 持久/临时节点 + Watch 机制 通过 Watch 机制监听 ZNode 变化,节点间用数据变更当“信号”传递消息,早期 Kafka 用过这种方式。
  • ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode。

  • 不同于文件系统,每个节点都可以保存数据,每一个 ZNode 默认能够存储 1MB 的数据,每个 ZNode 都可以通过其路径唯一标识,每个节点都有一个版本(version),版本从0开始计数。

Zookeeper 安装

  • 运行 Zookeeper 需要安装 JDK1.8+。我这里使用 OpenJDK11

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo mkdir -p /usr/local/jdk
cd /usr/local/jdk
sudo wget https://mirrors.tuna.tsinghua.edu.cn/Adoptium/11/jdk/x64/linux/OpenJDK11U-jdk_x64_linux_hotspot_11.0.28_6.tar.gz
sudo tar -zxvf OpenJDK11U-jdk_x64_linux_hotspot_11.0.28_6.tar.gz
sudo ln -s jdk-11.0.28+6 jdk11
# 配置环境变量
vim /etc/profile # 添加如下内容
export JAVA_HOME=/usr/local/jdk/jdk11
export PATH=$JAVA_HOME/bin:$PATH
# 立即生效
source /etc/profile
# 查看java版本
java -version
openjdk version "11.0.28" 2025-07-15
OpenJDK Runtime Environment Temurin-11.0.28+6 (build 11.0.28+6)
OpenJDK 64-Bit Server VM Temurin-11.0.28+6 (build 11.0.28+6, mixed mode)

单机安装

1
2
3
4
5
6
# 下载
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz
# 解压
tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz
# 配置个软连接,方便以后升级
ln -s apache-zookeeper-3.8.4-bin zookeeper
  • 修改配置文件

1
2
3
4
cd zookeeper/conf
cp zoo_sample.cfg zoo.cfg
# 建议修改 zoo.cfg 配置文件,将 dataDir=/tmp/zookeeper 修改为指定的data目录
vim zoo.cfg

zoo.cfg 参数说明

配置项 说明 默认值 单位 / 备注
tickTime ZooKeeper 时间配置中的基本单位 2000 毫秒
initLimit follower 初始化连接到 leader 的最大时长,单位为 tickTime 倍数 10 10 × tickTime = 20000 ms
syncLimit follower 与 leader 数据同步的最大时长,单位为 tickTime 倍数 5 5 × tickTime = 10000 ms
dataDir 数据和日志存储目录(未指定 dataLogDir 时,日志也会保存在此目录) /tmp/zookeeper 目录路径
clientPort 客户端连接 ZooKeeper 的端口号 2181 默认 2181
maxClientCnxns 单个客户端最大并发连接数 60 超过限制后新连接会被拒绝
autopurge.snapRetainCount 快照文件保留个数,超过数量的将会被清理 3 默认 3
autopurge.purgeInterval 清理任务执行间隔时间,单位小时,0 表示不自动清理 1 1 小时
  • 启动 zookeeper

1
2
3
4
5
6
7
8
9
10
11
12
cd zookeeper
# 启动
bin/zkServer.sh start
# 指定配置文件
bin/zkServer.sh start conf/zoo.cfg

# 停止
bin/zkServer.sh stop
# 查看状态
bin/zkServer.sh status
# 查看版本
./bin/zkServer.sh version

集群安装

ZooKeeper 集群角色

1. Leader(领导者)
  • 职责:

    • 事务请求(写操作)的唯一调度者和处理者,保证集群事务处理的顺序性;
    • 集群内部各个服务器的调度者;
    • 对于 createsetDatadelete 等写操作请求,统一转发给 Leader 处理;
    • Leader 负责决定编号、执行操作,这个过程称为 事务
  • 三台虚拟机 zoo.cfg 文件末尾添加配置,启动时会自动选举出 Leader 角色,则其余就是 Follower 角色。

1
2
3
server.1=10.250.0.229:2888:3888
server.2=10.250.0.152:2888:3888
server.3=10.250.0.36:2888:3888
2. Follower(跟随者)
  • 职责:

    • 处理客户端非事务(读操作)请求(可以直接响应);
    • 转发事务请求给 Leader;
    • 参与集群 Leader 选举投票。

leader节点可以处理读写请求,follower只可以处理读请求。follower在接到写请求时会把写请求转发给leader来处理。

3. Observer(观察者)
  • 职责:

    • 对于非事务请求(读操作)可以独立处理;
    • 对于事务请求会转发给 Leader 处理;
    • 接收来自 Leader 的 inform 信息,更新本地存储;
    • 不参与提交和选举投票;
    • 通常用于 提升集群非事务处理能力,不影响集群事务处理性能。
  • 配置一个 ID 为 4 的观察者节点:

1
server.4=10.250.0.56:2888:3888:observer

集群搭建

  • 环境准备:4台服务器,按照 单机安装 的方式准备好 Zookeeper 环境

1
2
3
4
10.250.0.229
10.250.0.152
10.250.0.36
10.250.0.56
  • zoo.cfg 文件末尾添加配置

1
2
3
4
server.1=10.250.0.229:2888:3888
server.2=10.250.0.152:2888:3888
server.3=10.250.0.36:2888:3888
server.4=10.250.0.56:2888:3888:observer
  • 分别在 dataDir 目录下创建 myid 文件,在文件中添加与 server 对应的编号(注意:上下不要有空行,左右不要有空格)

  • 分别启动 Zookeeper 服务器

1
2
3
4
5
# 分别启动4个节点的zookeeper server
bin/zkServer.sh start

# 查看状态,可以看到节点角色类型
bin/zkServer.sh status

集群最少节点要求和扩容规则

  • ZooKeeper 使用 多数派(quorum)机制 来保证数据一致性

1
2
3
1.集群总节点数 N
2.容忍的宕机节点数 F = (N-1)/2(向下取整)
3.要保证集群可用,需要 大于 N/2 的节点存活
  • 集群扩容规则

1
2
3
4
5
6
1.节点总数必须是奇数
奇数节点可以保证多数派投票机制正常
偶数节点不推荐,容错能力不增加(比如 4 台,仍然只容忍 1 台宕机)

2.每次扩容建议 +2 节点
这样既保持奇数,又增加 quorum 容错能力
  • 最少节点与容错能力表格

集群总节点数 N 容忍宕机数 F 可用 quorum 节点数 备注
1 0 1 不推荐,无法容忍故障
2 0 2 不推荐,1 台宕机就不可用
3 1 2 最小可用生产集群
5 2 3 推荐生产集群规模
7 3 4 高可用大集群
9 4 5 更大集群,高容错
11 5 6 极高可用场景

ZooKeeper 默认端口说明

端口 用途 说明
2181 客户端连接端口 客户端通过这个端口访问 ZooKeeper
2888 集群内部通信 follower 与 leader 之间同步数据
3888 leader 选举端口 集群选举 leader 使用
8080 (可选) admin/metrics web端口 如果开启了 adminServer
1
2
3
4
5
6
7
8
9
10
11
12
# 永久开启端口
sudo firewall-cmd --permanent --add-port=2181/tcp
sudo firewall-cmd --permanent --add-port=2888/tcp
sudo firewall-cmd --permanent --add-port=3888/tcp
# 如果使用 adminServer
sudo firewall-cmd --permanent --add-port=8080/tcp

# 重新加载防火墙配置
sudo firewall-cmd --reload

# 查看是否开放成功
sudo firewall-cmd --list-all

客户端连接

  • 命令行

1
2
3
4
# 默认连接 127.0.0.1:2181
bin/zkCli.sh
# 指定 -server ip:port,如果是集群,则连接任意一个节点,ZooKeeper 会自动处理与 Leader/Follower 的交互
bin/zkCli.sh -server 127.0.0.1:2181

客户端命令简介:参考官网

命令 语法示例 功能描述 常用参数及说明 示例
help help 显示所有操作命令 help
version version 查看客户端和服务器版本信息 version
connect connect host:port 连接到指定 ZooKeeper 服务器 host:port: 服务器地址 connect 127.0.0.1:2181
close close 关闭当前会话 ,通过 connect 可重连 close
quit quit 退出客户端 quit
ls ls [-s] [-w] [-R] path 查看节点的子节点 - -w: 监听子节点变化
- -s: 显示节点状态信息
- -R: 递归查看
ls -s -w /zk_test
getAllChildrenNumber getAllChildrenNumber path 获取某节点所有子节点的总数 getAllChildrenNumber /zk_test
getEphemerals getEphemerals path 获取某路径下所有临时节点 getEphemerals /zk_test
create create [-s] [-e] [-c] [-t ttl] path [data] [acl] 创建节点 - -s: 顺序节点
- -e: 临时节点
- -c: 容器节点
- -t ttl: TTL节点,单位毫秒
create -e /zk_test_ephemeral "temp_data"
get get [-s] [-w] path 获取节点数据信息 - -s: 显示节点状态信息
- -w: 监听节点变化
get -s -w /zk_test
set set [-s] [-v version] path data 设置节点数据 - -s: 显示节点状态信息
- -v: 指定版本号
set /zk_test "new_data"
stat stat [-w] path 查看节点状态信息 - -w: 监听节点变化 stat -w /zk_test
sync sync path 同步指定节点数据 sync /zk_test
delete delete [-v version] path 删除某一节点(无子节点) - -v: 节点版本号 delete /zk_test
deleteall deleteall path 递归删除某一节点及其子节点 deleteall /zk_test
getAcl getAcl [-s] path 获取节点访问控制信息 - -s: 显示节点状态信息 getAcl /zk_test
setAcl setAcl [-s] [-v version] [-R] path acl 设置节点访问控制列表 - -s: 显示节点状态信息
- -v: 指定版本号
- -R: 递归设置
setAcl /zk_test world:anyone:r
listquota listquota path 查看节点配额信息 listquota /zk_test
setquota setquota [-n] [-b] val path 对节点增加限制 - -n: 子节点最大个数
- -b: 数据值最大长度,-1 表示无限制
setquota -n 5 /zk_test
delquota delquota [-n | -b] path 删除节点配额限制 - -n: 删除子节点数限制
- -b: 删除数据值大小限制
delquota -n /zk_test
config config 查看服务器配置 config
whoami whoami 查看当前会话身份 whoami
  • GUI 工具

名称 类型 / 运行方式 优点 注意事项
PrettyZoo 桌面应用(JavaFX)(GitHub) 支持 Mac/Windows/Linux,界面友好;支持节点创建/删除/更新/查询,ACL 管理,多 ZK 实例管理,SSH 隧道等功能。(GitHub) 项目已经 archived,维护可能不活跃。最新版可能在兼容性或 Bug 修复方面不如活跃项目。也可能需要自己构建或调试。(GitHub)
ZooNavigator Web 界面 + 可 Docker 部署或本地启动(GitHub) 功能丰富;支持多个 Zookeeper 版本(如 3.5.x ~ 3.9.x);浏览 / 编辑 /搜索节点;导入导出配置;支持浏览器访问,无需本地 heavy GUI。(GitHub) 因为 Web 应用,可能对浏览器安全策略与网络延迟敏感;需要部署自己版本或 Docker;如果要求本地脱机操作时,有些功能可能稍不如桌面应用。
ZooKeeper Assistant 桌面/管理员面板类型(支持监控界面等)(DEV Community) 除了浏览节点树以外,还提供健康状态监控(延迟、请求数等)、不同数据格式支持(JSON/XML 等)、导入/导出节点数据、命令行操作集成。(DEV Community) 有些功能可能在 Mac 上兼容性或视觉体验需要调试;具体版本支持情况要看最近更新。某些监控界面可能依赖于 ZK 的指标或插件。

Zookeeper 节点类型

节点类型 生命周期说明 创建命令示例 特点说明
持久节点 (Persistent) 节点一直存在,除非手动删除,即使客户端会话关闭,节点也不会消失 create /locks 适合存储配置信息、元数据等持久数据
临时节点 (Ephemeral) 客户端会话关闭(异常或超时)时,节点自动被删除 create -e /locks/DBLock 常用于分布式锁、临时会话数据
有序节点 (Sequential) 在持久或临时节点基础上,增加有序编号,ZooKeeper 自动在节点名后加递增序号 create -e -s /jobs/job 常用于分布式锁、队列等需要顺序的场景
容器节点 (Container) V3.5.3+,当容器节点下的最后一个子节点被删除后,容器节点也会自动删除 create -c /work 适合分布式任务临时目录、动态数据目录
TTL 节点 (TTL) 在指定 TTL 时间内未修改且无子节点,节点会被自动删除(需开启 extendedTypesEnabled=true 配置) create -t 3000 /ttl_node 适合临时缓存、临时状态数据,过期自动清理
  • 注意

    • 同一级节点 key 名称是唯一的
    • 创建节点时,必须要带上全路径
  • 节点状态信息

1
2
3
4
5
6
7
8
9
10
11
12
[zk: localhost:2181(CONNECTED) 16] stat /test
cZxid = 0x100000002 # Znode创建的事务id
ctime = Mon Sep 15 09:44:51 UTC 2025 # 创建时间
mZxid = 0x100000004 # 最后一次修改事务id
mtime = Mon Sep 15 09:47:12 UTC 2025 # 最后一次修改时间
pZxid = 0x400000004 # 表示该节点的子节点列表最后一次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是修改子节点的数据内容则不影响该ID(注意: 只有子节点列表变更了才会变更pzxid,子节点内容变更不会影响pzxid)
cversion = 1 # 子节点的版本号。当znode的子节点有变化时,cversion 的值就会增加1。
dataVersion = 1 # znode的数据版本号。每次对节点进行set操作,dataVersion的值都会增加1(即使设置的是相同的数据),可有效避免了数据更新时出现的先后顺序问题
aclVersion = 0 # znode的ACL版本号。每次对节点进行ACL设置,aclVersion的值都会增加1
ephemeralOwner = 0x0 # 如果该节点为临时节点, ephemeralOwner值表示与该节点绑定的session id。如果不是, ephemeralOwner值为0(持久节点)。
dataLength = 3 # znode的数据长度
numChildren = 1 # znode的子节点数量(只统计直接子节点的数量)

Zookeeper 监听机制

  • watch机制,顾名思义是一个监听机制。Zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发生时才会触发监听,通知给客户端。

  • 监听的对象是事件,支持的事件类型如下:

1
2
3
4
5
6
7
- None: 连接建立事件
- NodeCreated: 节点创建
- NodeDeleted: 节点删除
- NodeDataChanged:节点数据变化
- NodeChildrenChanged:子节点列表变化
- DataWatchRemoved:节点监听被移除
- ChildWatchRemoved:子节点监听被移除
  • 监听特性

特性 说明
一次性触发 Watch 是一次性的,一旦被触发就会被移除。再次使用时需要重新注册。
客户端顺序回调 Watch 回调是顺序串行执行的,客户端只有在回调完成后才能看到最新的数据状态。
轻量级 Watcher 回调逻辑不应过多,以免阻塞或影响其他 Watch 的执行。
最小通信单位 WatchEvent 是最小的通信单位,只包含通知状态、事件类型和节点路径,不包含节点数据变化前后的具体内容。
时效性 Watcher 仅在当前 Session 完全失效时才无效。如果 Session 快速重连成功,Watcher 依然有效,可继续接收通知。
  • 可以开启监听的命令

1
2
3
4
5
6
#监听节点数据的变化
get -w path
stat -w path

#监听子节点增减的变化
ls -w path

永久性 Watch

  • 在被触发之后,仍然保留,可以继续监听ZNode上的变更,是Zookeeper 3.6.0版本新增的功能

  • 创建监听

1
2
3
4
5
addWatch [-m mode] path

# mode:
# - PERSISTENT: 持久化订阅,针对当前节点的修改和删除事件,以及当前节点的子节点的删除和新增事件。
# - PERSISTENT_RECURSIVE: 持久化递归订阅(这个是默认值),在PERSISTENT的基础上,增加了子节点修改的事件触发,以及子节点的子节点的数据变化都会触发相关事件(满足递归订阅特性)
  • 删除监听

1
2
3
4
5
6
# 普通一次性 Watch 不需要手动删除,触发后会自动移除;removewatches 主要用于持久 Watch(persistent watch)。
removewatches path [-c|-d|-a] [-l]
# -c: 仅删除当前客户端的 Watch
# -d: 删除指定节点的所有 Watch(包括其他客户端注册的)
# -a: 删除所有节点的所有 Watch(包括其他客户端的 Watch),慎用!!!
# -l: 显示被删除的 Watch 列表

监听器应用场景

类型 特点 应用场景举例 适合的节点类型
临时监听(一次性 Watch) - 触发一次后自动移除
- 客户端需手动重新注册
- 轻量级,适合单次通知
1. 配置中心:配置变化时通知客户端,客户端收到通知后重新拉取最新配置
2. 分布式锁:节点删除(锁释放)后通知等待的客户端重新竞争锁
3. 主从选举:主节点宕机后,其他节点收到通知重新选主
持久节点(Persistent)
临时节点(Ephemeral,用于锁和选主)
永久监听(Persistent Watch) - 注册后持续有效,直到客户端主动移除
- 支持子节点变化、数据变化的长期监听
1. 服务发现:客户端长期监听服务节点变化,节点上线/下线时自动更新本地服务列表
2. 监控告警:监控重要节点状态,节点数据变化或被删除时自动触发告警
3. 分布式缓存:缓存节点变化时,通知客户端刷新缓存
持久节点(Persistent)

ACL权限控制

  • ZooKeeper 默认情况下,所有节点的权限都是 OPEN_ACL_UNSAFE ,任何客户端都可以读写任意节点数据。

  • 生产环境中,通常需要限制对节点的访问权限,即 ACL 权限控制。

  • ZooKeeper 里的 ACL(Access Control List,访问控制列表) 主要用于控制 谁可以对某个节点做什么操作,它是 ZooKeeper 提供的安全机制之一。

ACL 的作用

  • 限制访问:只允许授权用户或客户端对指定节点进行读、写、删除等操作。

  • 防止误操作:保护重要节点不被未授权的客户端修改或删除。

  • 安全隔离:不同的应用或团队可以在同一 ZooKeeper 集群里安全共存。

ACL 的组成

  • zookeeper 的 acl 通过 scheme:id:permissions 来构成权限列表。

    • scheme:授权的模式,代表采用的某种权限机制,包括 world、auth、digest、ip、super 几种。
    • id:授权对象,代表允许访问的用户。如果我们选择采用 IP 方式,使用的授权对象可以是一个 IP 地址或 IP 地址段;而如果使用 Digest 或 Super 方式,则对应于一个用户名。如果是 World 模式,是授权系统中所有的用户。
    • permissions:授权的权限,权限组合字符串,由 cdrwa 组成,其中每个字母代表支持不同权限, 创建权限 create©、删除权限 delete(d)、读权限 read®、写权限 write(w)、管理权限admin(a)。

常见的 scheme 类型

Scheme 说明 示例
world 开放给所有用户,仅可设置为 anyone 代表所有客户端 world:anyone:r
auth 已通过 addauth 添加认证的客户端 auth:user1:rw
digest 用户名+密码认证(常用),user:pwd 需要加密存储 digest:user1:password:rw
ip 基于 IP 地址控制访问 ip:192.168.1.10:r
super 超级用户,拥有所有权限 super:admin:secret

权限类型

权限字符 权限名称 允许的操作/命令示例 说明
r 读取(Read) get /node
ls /node
getAcl /node
允许读取节点数据和子节点列表
w 写入(Write) set /node data 允许修改节点数据
c 创建(Create) create /node/sub "data" 允许在当前节点下创建子节点
d 删除(Delete) delete /node/sub 允许删除当前节点的子节点
a 管理(Admin) setAcl /node acl 允许修改 ACL 权限

典型应用场景

认证方式(scheme) 权限类型(permissions) 典型 ACL 配置示例 应用场景 特点说明
world r(只读) world:anyone:r 公共配置节点,所有客户端都可读取 简单、无认证,适合对安全性要求不高的只读场景
auth r,w,c,d,a(可组合) auth:user:rwcd 内部应用共享节点,需客户端认证 需先 addauth digest user1:password 添加认证,适合多客户端共享
digest(常用) r,w,c,d,a(可组合) digest:user:secret:crwda 高安全节点,配置中心,分布式锁 用户名+密码认证,需加密存储密码,灵活安全
ip r,w,c,d,a(可组合) ip:192.168.1.100:r 基于 IP 限制访问的场景 快速控制某些固定 IP 可访问,适合内部网络应用

ACL 相关命令

命令 语法 功能说明 示例
getAcl getAcl path 读取指定节点的 ACL getAcl /my_node
setAcl setAcl path acl 设置指定节点的 ACL setAcl /my_node world:anyone:crdwa
create create path data [acl] 创建节点时指定 ACL create /secure_node "secret_data" digest:user1:pwd:crwa
addAuth addauth scheme auth 添加认证用户(类似登录) addauth digest user1:password
deleteAcl(不存在) setAcl path world:anyone: 删除节点 ACL(设为空或全开放) setAcl /my_node world:anyone:

authdigest 的区别

  • 使用 auth 时,需先 addauth digest user1:password 添加认证,setAcl 时,使用 auth:user1:rw,这里是为已经登录的用户设置节点权限,所以不需要设置密码

  • 使用 digest 时,无需进行登录认证,所以需要指定密码,即setAcl 时,使用 digest:user1:password:rw

  • digest 的密码是经过加密的,所以不能直接使用明文密码

1
2
3
4
5
6
7
8
9
10
# 加密密码
echo -n user:123456 | openssl dgst -binary -sha1 | openssl base64
# 输出
6DY5WhzOfGsWQ1XFuIyzxkpwdPo=

# zookeeper客户端中设置权限
setAcl /name digest:user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=:cdrwa

# 登录时密码是明文
addauth digest user:123456
  • 无论使用 digest 还是 auth,在需要访问节点前,都需要先登录。

super 超级管理员

  • 拥有全部节点的所有权限: crwda

  • 设置超级管理员

1
2
3
4
5
6
7
# 加密密码,用户和密码可以随意设置
echo -n admin:123456 | openssl dgst -binary -sha1 | openssl base64
# 输出
0uek/hZ/V9fgiM35b0Z2226acMQ=

# 打开 conf/zoo.cfg 文件并编辑,在文件中添加下面内容
DigestAuthenticationProvider.superDigest=admin:0uek/hZ/V9fgiM35b0Z2226acMQ=
  • 重新启动服务后登录客户端进行测试

1
2
3
4
5
6
7
8
9
10
11
# 创建节点并设置权限,这里将节点授权给用户user
[zk: localhost:2181(CONNECTED) 10] create /testNode 666 digest:user:6DY5WhzOfGsWQ1XFuIyzxkpwdPo=:rw
Created /testNode
# 查看节点内容被拒绝
[zk: localhost:2181(CONNECTED) 11] get /testNode
Insufficient permission : /testNode
# 登录super用户,验证超级用户是否有权限访问节点
[zk: localhost:2181(CONNECTED) 12] addauth digest admin:123456
# 此时查看节点内容就可以了
[zk: localhost:2181(CONNECTED) 13] get /testNode
666

4字母命令

什么是 4 字母命令?

  • ZooKeeper 提供了一组简短的 4个字母的管理命令(Four Letter Words Commands, 4lw),可以通过 TCP 连接 ZooKeeper 端口(默认 2181)发送这些命令,快速查看或管理 ZooKeeper 状态。

  • 常用的 4字母命令

命令 引入版本 功能描述 示例
conf 3.3.0 打印服务相关配置的详细信息 echo conf | nc 127.0.0.1 2181
cons 3.3.0 列出所有连接到该服务器的客户端连接/会话详细信息,包括接收/发送的包数量、会话ID、操作延迟、最后操作执行时间等 echo cons | nc 127.0.0.1 2181
crst 3.3.0 重置所有连接的连接和会话统计信息 echo crst | nc 127.0.0.1 2181
dump - 列出重要的会话和临时节点信息,仅在 Leader 节点上有效 echo dump | nc 127.0.0.1 2181
envi - 打印服务环境的详细信息 echo envi | nc 127.0.0.1 2181
reqs - 列出未经处理的请求 echo reqs | nc 127.0.0.1 2181
ruok - 测试服务是否处于正常状态;正常返回 imok echo ruok | nc 127.0.0.1 2181
stat - 输出关于性能和客户端连接的列表信息 echo stat | nc 127.0.0.1 2181
srst - 重置服务器统计信息 echo srst | nc 127.0.0.1 2181
srvr 3.3.0 列出连接服务器的详细信息 echo srvr | nc 127.0.0.1 2181
wchs 3.3.0 列出服务器 Watch 的详细信息 echo wchs | nc 127.0.0.1 2181
wchc 3.3.0 通过会话列出服务器 Watch 的详细信息,输出与 Watch 相关的会话列表 echo wchc | nc 127.0.0.1 2181
wchp 3.3.0 通过路径列出服务器 Watch 的详细信息,输出与会话相关的路径 echo wchp | nc 127.0.0.1 2181
mntr 3.4.0 输出可用于检测集群健康状态的关键指标变量列表 echo mntr | nc 127.0.0.1 2181

开启 4字母命令

  • 在 ZooKeeper 3.5.0 及之后的版本,4lw 命令默认是禁用的,必须在配置文件(zoo.cfg)中显式开启。

1
2
3
4
# 表示允许所有 4lw 命令都能用(风险最大)
4lw.commands.whitelist=*
# 这样只允许执行 stat、conf、ruok 这几个命令。
4lw.commands.whitelist=stat,conf,ruok
  • 使用方法

1
2
3
4
# 如果没有安装 nc,可以使用 yum 安装
yum install nc -y
# 查看节点状态
echo stat | nc 127.0.0.1 2181

Zookeeper Java Client

Zookeeper 官方Java客户端

  • ZooKeeper官方的客户端API提供了基本的操作。例如,创建会话、创建节点、读取节点、更新数据、删除节点和检查节点是否存在等。不过,对于实际开发来说,ZooKeeper官方API有一些不足之处,具体如下:

    • ZooKeeper的Watcher监测是一次性的,每次触发之后都需要重新进行注册。
    • 会话超时之后没有实现重连机制。
    • 异常处理烦琐,ZooKeeper提供了很多异常,对于开发人员来说可能根本不知道应该如何处理这些抛出的异常。
    • 仅提供了简单的byte[]数组类型的接口,没有提供Java POJO级别的序列化数据处理接口。
    • 创建节点时如果抛出异常,需要自行检查节点是否存在。
    • 无法实现级联删除。
    • 总之,ZooKeeper官方API功能比较简单,在实际开发过程中比较笨重,一般不推荐使用。
  • 项目引入依赖时,最好保持与服务端版本一致,否则可能会有一些兼容性的问题

1
2
3
4
5
6
<!-- zookeeper client -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.4</version>
</dependency>

Zookeeper 第三方Java客户端 Curator

  • Curator是Netflix公司开源的一套ZooKeeper客户端框架,和ZkClient一样它解决了非常底层的细节开发工作,包括连接、重连、反复注册Watcher的问题以及NodeExistsException异常等。

  • Curator是Apache基金会的顶级项目之一,Curator具有更加完善的文档,另外还提供了一套易用性和可读性更强的Fluent风格的客户端API框架。

  • Curator还为ZooKeeper客户端框架提供了一些比较普遍的、开箱即用的、分布式开发用的解决方案,例如Recipe、共享锁服务、Master选举机制和分布式计算器等,帮助开发者避免了“重复造轮子”的无效开发工作。

  • 在实际的开发场景中,使用Curator客户端就足以应付日常的ZooKeeper集群操作的需求。

  • 引入依赖说明:

模块 依赖关系 功能定位 典型功能举例 常用场景
curator-client 依赖 zookeeper 连接管理、重试策略、底层 API 连接会话管理、RetryPolicy 需要最轻量的 ZooKeeper 客户端
curator-framework 依赖 curator-client 高层 API 封装,简化 ZK 操作 创建节点、Watcher 管理、自动重连 通用 ZooKeeper 客户端开发
curator-recipes 依赖 curator-framework → curator-client 分布式模式现成实现 分布式锁、Leader 选举、队列、Barrier 直接用分布式工具,无需自己实现

使用建议

  • 如果你只想轻量访问 ZooKeeper → curator-client 就够了,但几乎没人单独用。

  • 如果你想方便操作 ZooKeeper API → curator-framework,大部分情况都适用。

  • 如果你想用分布式锁、选举、Barrier → curator-recipes(它会自动引入前两个)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- zookeeper client -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.4</version>
</dependency>

<!--curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.9.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>