ZooKeeper 速查表
本文档提供 ZooKeeper 常用命令和配置的快速参考。
命令行操作
服务管理
# 启动服务
zkServer.sh start
# 停止服务
zkServer.sh stop
# 重启服务
zkServer.sh restart
# 查看状态
zkServer.sh status
# 前台运行(调试用)
zkServer.sh start-foreground
客户端连接
# 连接本地服务
zkCli.sh
# 连接指定服务器
zkCli.sh -server localhost:2181
# 连接集群
zkCli.sh -server server1:2181,server2:2181,server3:2181
# 带超时连接
zkCli.sh -server localhost:2181 -timeout 5000
节点操作
# 创建持久节点
create /path "data"
# 创建临时节点
create -e /path "data"
# 创建顺序节点
create -s /path "data"
# 创建临时顺序节点
create -e -s /path "data"
# 创建容器节点
create -c /path "data"
# 创建 TTL 节点
create -t 30000 /path "data"
# 获取节点数据
get /path
# 获取节点数据(含状态)
get -s /path
# 设置节点数据
set /path "new-data"
# 条件更新(指定版本)
set /path "data" 1
# 删除节点
delete /path
# 条件删除
delete /path 1
# 递归删除
deleteall /path
# 检查节点是否存在
stat /path
# 列出子节点
ls /path
# 列出子节点(含状态)
ls -s /path
# 递归列出
ls -R /path
ACL 操作
# 获取 ACL
getAcl /path
# 设置 ACL
setAcl /path world:anyone:rwcda
# 设置 digest ACL
setAcl /path digest:user:password:rwcda
# 设置 IP ACL
setAcl /path ip:192.168.1.0/24:rwcda
# 添加认证
addauth digest user:password
# 递归设置 ACL
setAcl -R /path world:anyone:r
配置操作
# 打印配置
config
# 动态添加节点
reconfig -add server.4=192.168.1.104:2888:3888:participant
# 动态移除节点
reconfig -remove 4
其他命令
# 打印历史命令
history
# 执行历史命令
redo 1
# 退出客户端
quit
# 打印帮助
help
四字命令
# 检查服务器状态
echo stat | nc localhost 2181
# 检查是否存活
echo ruok | nc localhost 2181
# 查看配置
echo conf | nc localhost 2181
# 查看连接
echo cons | nc localhost 2181
# 查看环境变量
echo envi | nc localhost 2181
# 查看监控统计
echo mntr | nc localhost 2181
# 查看服务器状态
echo srvr | nc localhost 2181
# 查看是否只读
echo isro | nc localhost 2181
# 重置统计
echo srst | nc localhost 2181
# 查看监视器
echo wchs | nc localhost 2181
# 查看监视器详情
echo wchc | nc localhost 2181
# 查看监视器路径
echo wchp | nc localhost 2181
# 查看等待队列
echo dump | nc localhost 2181
配置参数
核心参数
| 参数 | 默认值 | 说明 |
|---|---|---|
tickTime | 2000 | 心跳间隔(毫秒) |
dataDir | 无 | 数据目录 |
dataLogDir | dataDir | 事务日志目录 |
clientPort | 2181 | 客户端端口 |
initLimit | 10 | Follower 初始化超时(心跳数) |
syncLimit | 5 | Follower 同步超时(心跳数) |
性能参数
| 参数 | 默认值 | 说明 |
|---|---|---|
preAllocSize | 65536 | 预分配日志大小(KB) |
snapCount | 100000 | 快照间隔 |
maxClientCnxns | 60 | 最大客户端连接数 |
minSessionTimeout | 2*tickTime | 最小会话超时 |
maxSessionTimeout | 20*tickTime | 最大会话超时 |
清理参数
| 参数 | 默认值 | 说明 |
|---|---|---|
autopurge.snapRetainCount | 3 | 保留快照数量 |
autopurge.purgeInterval | 1 | 清理间隔(小时) |
集群参数
# 集群配置
server.1=host1:2888:3888
server.2=host2:2888:3888
server.3=host3:2888:3888
# Observer 配置
peerType=observer
server.4=host4:2888:3888:observer
ZNode 类型
| 类型 | 创建参数 | 说明 |
|---|---|---|
| 持久节点 | 无 | 永久存在 |
| 临时节点 | -e | 会话结束删除 |
| 持久顺序节点 | -s | 持久 + 序号 |
| 临时顺序节点 | -e -s | 临时 + 序号 |
| 容器节点 | -c | 子节点删除后可能删除 |
| TTL 节点 | -t ms | 超时删除 |
ACL 权限
权限缩写
| 权限 | 缩写 | 说明 |
|---|---|---|
| READ | r | 读取数据和子节点 |
| WRITE | w | 写入数据 |
| CREATE | c | 创建子节点 |
| DELETE | d | 删除子节点 |
| ADMIN | a | 设置 ACL |
认证方案
| 方案 | 格式 | 说明 |
|---|---|---|
| world | world:anyone | 所有用户 |
| auth | auth:: | 已认证用户 |
| digest | digest:user:hash | 用户名密码 |
| ip | ip:addr/bits | IP 地址 |
| x509 | x509:dn | SSL 证书 |
预定义 ACL
// 完全开放
Ids.OPEN_ACL_UNSAFE // world:anyone:cdrwa
// 只读
Ids.READ_ACL_UNSAFE // world:anyone:r
// 创建者所有权限
Ids.CREATOR_ALL_ACL // auth::cdrwa
Java API 快速参考
创建连接
// 原生 API
ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, watcher);
// Curator
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString("localhost:2181")
.sessionTimeoutMs(5000)
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
client.start();
CRUD 操作
// 创建节点
zk.create("/path", data, acl, mode);
// 获取数据
byte[] data = zk.getData("/path", watch, stat);
// 设置数据
zk.setData("/path", data, version);
// 删除节点
zk.delete("/path", version);
// 检查存在
Stat stat = zk.exists("/path", watch);
// 获取子节点
List<String> children = zk.getChildren("/path", watch);
Curator 操作
// 创建
client.create().creatingParentsIfNeeded().forPath("/path", data);
// 获取
byte[] data = client.getData().forPath("/path");
// 设置
client.setData().forPath("/path", data);
// 删除
client.delete().deletingChildrenIfNeeded().forPath("/path");
// 检查存在
Stat stat = client.checkExists().forPath("/path");
// 获取子节点
List<String> children = client.getChildren().forPath("/path");
分布式锁
// 可重入锁
InterProcessMutex lock = new InterProcessMutex(client, "/lock");
lock.acquire();
try {
// 业务逻辑
} finally {
lock.release();
}
// 读写锁
InterProcessReadWriteLock rwLock = new InterProcessReadWriteLock(client, "/rwlock");
rwLock.readLock().acquire();
rwLock.writeLock().acquire();
Leader 选举
// LeaderLatch
LeaderLatch latch = new LeaderLatch(client, "/election");
latch.start();
latch.await();
boolean isLeader = latch.hasLeadership();
// LeaderSelector
LeaderSelector selector = new LeaderSelector(client, "/election", listener);
selector.start();
监控指标
关键指标
| 指标 | 说明 | 警戒值 |
|---|---|---|
zk_avg_latency | 平均延迟 | > 10ms |
zk_max_latency | 最大延迟 | > 100ms |
zk_packets_received | 接收包数 | - |
zk_packets_sent | 发送包数 | - |
zk_num_alive_connections | 活跃连接数 | 接近 maxClientCnxns |
zk_outstanding_requests | 待处理请求数 | > 10 |
zk_znode_count | 节点数 | - |
zk_watch_count | 监视器数 | - |
zk_ephemerals_count | 临时节点数 | - |
zk_approximate_data_size | 数据大小 | > 1GB |
zk_open_file_descriptor_count | 打开文件数 | 接近限制 |
zk_followers | Follower 数 | - |
zk_synced_followers | 同步 Follower 数 | < 半数 |
故障排查
常见错误
| 错误 | 原因 | 解决方案 |
|---|---|---|
ConnectionLoss | 连接断开 | 检查网络,重连 |
SessionExpired | 会话过期 | 重建会话 |
NoAuth | 无权限 | 添加认证 |
NoNode | 节点不存在 | 创建节点 |
NodeExists | 节点已存在 | 检查路径 |
BadVersion | 版本不匹配 | 获取最新版本 |
NotEmpty | 节点非空 | 先删除子节点 |
日志位置
# 默认日志目录
$ZOOKEEPER_HOME/logs/
# 事务日志
dataLogDir/version-2/
# 快照
dataDir/version-2/
JVM 参数
# 堆内存
-Xms2g -Xmx2g
# GC
-XX:+UseG1GC -XX:MaxGCPauseMillis=100
# GC 日志
-Xlog:gc*:file=gc.log
最佳实践
集群规划
- 使用奇数节点(3、5、7)
- 节点部署在不同机架
- 事务日志使用独立磁盘
客户端开发
- 使用 Curator 框架
- 合理设置会话超时
- 处理连接状态变化
- Watcher 触发后重新注册
性能优化
- 读写分离(Observer)
- 批量操作
- 合理设置 Watcher
- 控制节点数据大小
安全加固
- 启用认证
- 使用 SSL/TLS
- 设置 ACL
- 限制四字命令