Zookeeper 的典型应用场景有哪些?
结论先行:ZK 的四个高频场景是注册中心、配置管理、分布式锁、Master 选举;再往外还有命名服务、分布式队列、集群成员管理与元数据存储。共同点是“数据量小、变更不频繁、对一致性敏感”。
一、场景与数据结构对照
| 场景 | 节点结构 | 关键机制 |
|---|---|---|
| 注册中心 | /dubbo/com.X.Service/providers/… | 临时节点 + 会话 + watch |
| 配置管理 | /config/app/env/key | 持久节点 + watch 推送 |
| 分布式锁 | /lock/resource/lock-0000000001 | 临时顺序节点 + 监听前驱 |
| Master 选举 | /election/n_0000000001 | 临时顺序节点,最小序号为主 |
| 命名服务 | /service/db/primary | 持久节点存地址 |
| 集群成员 | /cluster/members/inst-1 | 临时节点,列表即成员 |
| 分布式队列 | /queue/item-0000000001 | 顺序节点,按序号消费 |
二、注册中心的目录约定(Dubbo 风格)
/dubbo
└── com.demo.UserService
├── providers
│ ├── dubbo://10.0.0.1:20880/...?timeout=3000 (临时节点)
│ └── dubbo://10.0.0.2:20880/...?timeout=3000
├── consumers
│ └── consumer://10.0.0.9/... (临时节点)
├── routers
└── configurators
提供者启动写临时节点,宕机后会话超时由服务端删除;消费者 watch providers 子节点变化,拿到全量 URL 列表并缓存到本地文件。
三、Master 选举示例
// 每个实例都尝试创建临时顺序节点,序号最小者为主
String path = client.create()
.withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
.forPath("/election/n_"); // 返回 /election/n_0000000007
String myNode = path.substring(path.lastIndexOf('/') + 1);
List<String> children = client.getChildren().forPath("/election");
Collections.sort(children); // 序号补零,字典序即大小序
boolean isLeader = myNode.equals(children.get(0));
if (!isLeader) {
// 只监听前一个节点,避免惊群
String prev = children.get(children.indexOf(myNode) - 1);
client.getData().usingWatcher(watcher).forPath("/election/" + prev);
}
四、选型判断
| 判断条件 | 结论 |
|---|---|
| 需要“排队 + 公平”,锁竞争激烈 | ZK 合适,顺序节点天然排队 |
| 只需要毫秒级短锁、QPS 很高 | Redis 更合适,ZK 写放大 |
| 配置项多、需要灰度与回滚 | 配置中心(Nacos/Apollo)更合适 |
| 只需要简单 KV 与 watch | etcd 更轻量 |
| 数据超过 1MB 或需要查询 | 都不合适,用数据库 |
| 需要消息堆积与重放 | 用 MQ,ZK 的顺序节点不适合高吞吐 |
| 只需要进程内协调 | 用 JVM 锁或本地队列,别引入 ZK |
五、落地前的三个自检
| 自检项 | 判断标准 |
|---|---|
| 单个节点数据是否远小于 1MB | 超过就只存引用,正文放对象存储 |
| 变更频率是否低于每秒几十次 | 更高就应该换注册中心或配置中心 |
| 团队是否已有同类组件在运行 | 为一小块功能新增一套 ZK,运维成本不划算 |
这三条过不了,说明 ZK 不是最优解,而不是 ZK 不好用。
常见追问
- 追问:ZK 做配置中心和 Nacos 的差别?ZK 只有 watch 通知,变更要自己拉全量、自己做版本与灰度;Nacos 提供推送、命名空间、灰度、回滚。
- 追问:为什么不用 ZK 存业务数据?单节点 1MB 限制、写要过半确认、无查询能力,吞吐与功能都不匹配。
- 追问:ZK 队列有什么问题?顺序节点靠父节点 cversion 递增,消费后节点要删除,大量堆积时清理成本高,不适合高吞吐消息场景。
小结
- 注册、配置、锁、选举是四大主场景,都符合“小数据 + 低频变更”。
- 临时节点管存活,顺序节点管排队,watch 管通知。
- ZK 强在协调语义,弱在吞吐与存储。
- 高 QPS 短锁用 Redis,配置管理用专业配置中心。