1892 字
约 6 分钟
0
Zookeeper 入门

Zookeeper 入门

1. 一句话简介

Zookeeper 是一个分布式协调服务,核心能力是把「分布式系统里多个节点需要一致协作的元信息」通过一个高可用的树形节点(Znode)存储机制统一管理起来,解决分布式系统中普遍存在的配置管理、命名服务、集群状态同步与协调一致等问题。本模块通过 Apache Curator(4.1.0,对应 ZK 3.5.x)客户端接入 Zookeeper,用它实现分布式锁:当 1000 个线程并发扣减同一个库存 count 时,基于 ZK 的临时顺序节点 + Watcher 机制配合 InterProcessMutex 可重入锁,再叠加自定义 @ZooLock 注解 + AOP 切面,让并发操作最终精确得到正确结果,而无需在业务代码中手写锁逻辑。

2. 什么时候使用

  • 多个应用实例需要保证对同一资源互斥访问:普通 JVM 内置的 synchronized/Lock 只作用于单进程,多实例部署时无法生效。Zookeeper 锁是跨进程、跨机器的,本模块用 1000 线程并发扣库存验证了它在多节点场景下的正确性。
  • 需要可重入、无单点风险的分布式锁:ZK 的分布式锁基于临时顺序节点实现,客户端断连时临时节点自动删除,锁随之自动释放,避免死锁;InterProcessMutex 支持可重入,同一线程可再次获取。
  • 需要统一的分布式配置管理与发现:把共享配置、服务注册信息写入 ZK 节点,各节点通过 Watcher 实时感知变化,实现配置和服务的动态更新。
  • 需要 Leader 选举、任务分配等一致性协调:ZK 天然支持选举类场景(Curator 的 LeaderLatchLeaderSelector),适合做主从选主、定时任务的一次性调度。
  • 写入以少量协调数据为主、以读为主的场景:ZK 数据量小,适合存储协调类元信息(锁、配置、状态),读性能优异。
  • 场景仅限单机应用:若只有一个实例、无多节点协作需求,引入 ZK 只会增加部署与运维复杂度,用 JVM 内置锁即可。
  • 作为业务数据或者大数据量的存储:ZK 是一款协调服务而非数据库,节点数据量大会严重影响性能,不适合存业务实体、日志或高吞吐消息。
  • 需要高吞吐写入的场景:ZK 写入必须由 Leader 单点执行并达成多数派确认,写入性能远低于读,不适合写密集的业务。
  • 需要极致低延迟获取分布式锁:每次加锁都要经过网络往返与集群协商,比本地锁或基于内存的 Redis 锁开销大,对延迟极敏感的场景需评估。
  • 希望轻量、不愿引入额外运维组件:ZK 独立部署需要维护集群、会话与节点,若已有 Redis,简单场景用 Redis 分布式锁也能覆盖,可避免多引入一套系统。

3. 常见业务场景

跨实例并发扣库存 / 防重复提交:对商品库存、订单号、幂等键做互斥,保证并发下数据一致。本模块的 AOP 切面在 @ZooLock(key = "buy", timeout = 1) 上加锁,超时未获取则抛出「请勿重复提交」异常;1000 线程并发把库存从 10000 扣到 0 且无超扣,正是这类秒杀/下单场景的典型演示。

声明式加锁(业务零侵入):通过自定义 @ZooLock 注解 + AOP 环绕通知,在方法执行前 lock.acquire()finallylock.release(),业务代码只需加一个注解即自动完成加解锁,无需关心锁的获取与释放细节,适合需要简单接入分布式锁的大规模业务方法。

动态业务维度加锁:通过 @LockKeyParam 把方法参数动态拼进锁 key。例如 @ZooLock(key="user") void update(@LockKeyParam({"id"}) User user),不同用户 ID 落到不同锁路径,互不阻塞,实现按用户、订单等维度细粒度加锁,而非全局一把锁造成的性能浪费。

分布式配置管理与节点协调:各应用实例连接同一 ZK,共享配置节点并通过 Watcher 监听变化,配置更新即时同步到所有节点;配合临时(ephemeral)节点和 Watcher,还能实现服务注册与发现、节点状态感知。

主从选举与强一致协调:在集群中通过 ZK 达成一致选出 Leader,保证同一时刻只有一个节点执行主任务(如同步任务、定时任务),其余节点作为备选,主节点故障后临时节点消失触发重新选举,这是任务调度和主备切换的常见实现。

4. 同类技术对比

维度 Zookeeper Redis etcd 数据库(MySQL)
核心定位 分布式协调服务 缓存/键值存储 分布式键值存储(协调) 关系型存储
实现分布式锁 支持,临时顺序节点,强一致、可重入 支持,SETNX/Redlock,需注意锁过期与续期 支持,基于租约(lease)+ 续期,强一致 支持有限,基于唯一索引 + 行锁,侵入业务
一致性保证 强一致(ZAB 协议,多数派) 弱一致(主从集群) 强一致(Raft,多数派) 强一致(事务)
数据模型 树形节点(Znode) String、Hash、ZSet 等 扁平键值 + 目录前缀 表 / 记录
配置管理 支持,Watcher 监听 不支持原生 支持,Watch 监听 需自建
服务发现/选举 强项,Leader 选举原生支持 不支持 强项,原生支持 不支持原生
读写性能 读快写慢(写入经 Leader 多数派) 读写都快(内存) 读写较快 最慢
学习与运维成本 较高,需独立集群 较低,生态成熟 中,Go 生态,YAML 简单 依赖已有数据库
适用规模 中小规模协调、节点数适中 高并发缓存/计数 云原生、容器(K8s 生态) 业务数据存储为主

选型建议:需要分布式锁、服务发现、Leader 选举等多类协调能力的传统 Java 分布式系统,选 Zookeeper(Curator 封装完善、锁可重入且无需手动续期);若仅需高并发下简单的分布式锁且团队已在用 Redis,可用 Redis 的 SETNX 方案,但要自行处理锁过期、误删与续期,适合对一致性要求不高、对延迟更敏感的场景;云原生 / Kubernetes 环境、追求轻量与便捷配置时优先 etcd(Raft 强一致、API 简单),且与容器生态融合好;数据库兜底方案只适合锁并发极低、可接受侵入业务逻辑的简单场景,不应作为分布式锁的常规选择。整体而言,多实例互斥 + 协调需求复杂时选 Zookeeper,纯锁 + 已有 Redis 选 Redis,云原生选 etcd。

Zookeeper 入门
http://www.clxhxhhr.top/posts/513/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。