答案
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 操作:
javaList<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. 数据快照和事务日志
事务日志:
- 记录所有写操作
- 用于数据恢复
- 顺序写入,性能高
快照:
- 定期保存内存状态
- 加速启动恢复
- 压缩存储
恢复流程:
- 加载最新快照
- 应用快照之后的事务日志
- 与 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 选举
- 分布式计数器
- 分布式队列
分布式锁示例:
javaInterProcessMutex lock = new InterProcessMutex( client, "/locks/my-lock" ); try { // 获取锁 lock.acquire(); // 执行业务逻辑 doSomething(); } finally { // 释放锁 lock.release(); }
Leader 选举示例:
javaLeaderSelectorListener 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"
集群间迁移:
- 停止写入
- 导出数据
- 导入新集群
- 切换客户端连接
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"; };