乐闻世界logo
搜索文章和话题

Zookeeper 有哪些高级特性?如何使用 Watcher、ACL 和事务操作?

2月21日 16:24

答案

Zookeeper 提供了多个高级特性,这些特性使得它在分布式系统中更加灵活和强大。

1. Watcher 机制

Watcher 特性

  • 一次性触发:触发后自动删除
  • 轻量级:只通知事件类型,不包含数据
  • 异步通知:通过回调函数处理

Watcher 类型

java
// 节点数据变化 zk.getData("/path", watcher, null); // 子节点变化 zk.getChildren("/path", watcher); // 节点存在性变化 zk.exists("/path", watcher);

事件类型

  • NodeCreated:节点创建
  • NodeDeleted:节点删除
  • NodeDataChanged:节点数据变化
  • NodeChildrenChanged:子节点变化

最佳实践

  • Watcher 触发后需要重新注册
  • 避免在 Watcher 中执行耗时操作
  • 使用 exists() 监听不存在的节点

2. ACL 权限控制

权限类型

  • CREATE:创建子节点
  • READ:读取节点数据
  • WRITE:更新节点数据
  • DELETE:删除子节点
  • ADMIN:设置 ACL

权限方案

java
// world:任何人 ZooDefs.Ids.OPEN_ACL_UNSAFE // auth:认证用户 new ACL(Perms.ALL, new Id("auth", "username:password")) // digest:用户名密码 new ACL(Perms.READ, new Id("digest", "username:password")) // ip:IP 地址 new ACL(Perms.READ, new Id("ip", "192.168.1.1")) // super:超级管理员

设置 ACL

java
// 创建节点时设置 ACL zk.create("/secure", data, ZooDefs.Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT); // 修改节点 ACL zk.setACL("/secure", ZooDefs.Ids.OPEN_ACL_UNSAFE, -1);

3. 事务操作

事务特性

  • 原子性:要么全部成功,要么全部失败
  • 顺序性:按提交顺序执行

multi 操作

java
List<Op> ops = new ArrayList<>(); // 创建节点 ops.add(Op.create("/multi/node1", "data1".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); // 更新数据 ops.add(Op.setData("/multi/node1", "newData".getBytes(), -1)); // 删除节点 ops.add(Op.delete("/multi/node1", -1)); // 执行事务 zk.multi(ops);

4. 四字命令

常用四字命令

bash
# 查看集群状态 echo stat | nc localhost 2181 # 查看连接信息 echo cons | nc localhost 2181 # 查看环境变量 echo envi | nc localhost 2181 # 查看配置 echo conf | nc localhost 2181 # 查看监控信息 echo mntr | nc localhost 2181 # 查看节点统计 echo dump | nc localhost 2181 # 重置连接统计 echo srst | nc localhost 2181 # 查看服务器状态 echo srvr | nc localhost 2181 # 查看观察者信息 echo wchs | nc localhost 2181

5. 数据快照和事务日志

事务日志

  • 记录所有写操作
  • 用于数据恢复
  • 顺序写入,性能高

快照

  • 定期保存内存状态
  • 加速启动恢复
  • 压缩存储

恢复流程

  1. 加载最新快照
  2. 应用快照之后的事务日志
  3. 与 Leader 同步差异数据

6. 客户端重连机制

自动重连

java
// 设置重试策略 RetryPolicy retryPolicy = new ExponentialBackoffRetry( 1000, // base sleep time 3 // max retries ); CuratorFramework client = CuratorFrameworkFactory.builder() .connectString("localhost:2181") .retryPolicy(retryPolicy) .build();

重连策略

  • ExponentialBackoffRetry:指数退避
  • RetryNTimes:固定次数重试
  • RetryUntilElapsed:超时重试
  • RetryOneTime:单次重试

7. 会话管理

会话状态

  • CONNECTING:连接中
  • CONNECTED:已连接
  • RECONNECTING:重连中
  • CLOSED:已关闭

会话超时

  • 客户端心跳维持会话
  • 超时后临时节点自动删除
  • 可配置超时时间

会话恢复

java
// 使用会话 ID 和密码恢复 byte[] password = zk.getSessionPasswd(); long sessionId = zk.getSessionId(); ZooKeeper newZk = new ZooKeeper( "localhost:2181", 30000, watcher, sessionId, password );

8. 容器节点(3.5+)

容器节点特性

  • 没有子节点时自动删除
  • 用于动态资源管理

使用场景

  • 锁的父节点
  • 临时资源组
java
// 创建容器节点 zk.create("/container", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.CONTAINER);

9. TTL 节点(3.5+)

TTL 节点特性

  • 设置过期时间
  • 超时自动删除
  • 需要启用 TTL 功能

启用 TTL

properties
# zoo.cfg zookeeper.extendedTypesEnabled=true

创建 TTL 节点

java
// 创建 TTL 节点 zk.create("/ttl-node", data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_WITH_TTL, new Stat(), 5000); // TTL 5秒

10. 高级客户端 Curator

Curator 框架特性

  • 连接管理
  • 重试机制
  • 分布式锁
  • Leader 选举
  • 分布式计数器
  • 分布式队列

分布式锁示例

java
InterProcessMutex lock = new InterProcessMutex( client, "/locks/my-lock" ); try { // 获取锁 lock.acquire(); // 执行业务逻辑 doSomething(); } finally { // 释放锁 lock.release(); }

Leader 选举示例

java
LeaderSelectorListener listener = new LeaderSelectorListener() { @Override public void takeLeadership() { // 成为 Leader 后执行 while (true) { // 保持 Leader 状态 Thread.sleep(1000); } } }; LeaderSelector selector = new LeaderSelector( client, "/leader", listener ); selector.start();

11. 数据迁移和备份

数据导出

bash
# 使用 zkCli 导出数据 zkCli.sh -server localhost:2181 get /path > backup.txt

数据导入

bash
# 导入数据 zkCli.sh -server localhost:2181 create /path "data"

集群间迁移

  1. 停止写入
  2. 导出数据
  3. 导入新集群
  4. 切换客户端连接

12. 监控和告警

监控指标

  • 节点状态
  • 延迟指标
  • 吞吐量
  • 连接数
  • 内存使用

告警策略

  • Leader 切换告警
  • 延迟超阈值告警
  • 连接数超限告警
  • 内存使用率告警

13. 安全加固

安全措施

  • 启用 SASL 认证
  • 配置 ACL 权限
  • 网络隔离
  • 定期备份
  • 日志审计

SASL 认证配置

properties
# jaas.conf Server { org.apache.zookeeper.server.auth.DigestLoginModule required user_super="admin"; }; Client { org.apache.zookeeper.server.auth.DigestLoginModule required username="admin" password="admin"; };
标签:Zookeeper