Skip to content

P84 分布式锁:Redis 还是 Zookeeper? ​

面试题:分布式锁用 Redis 还是 Zookeeper?怎么选?

1. 两种实现 ​

Redis 分布式锁 ​

bash
SET lock:order:1001 uuid NX EX 30   # 原子:不存在才设置 + 过期时间
java
// 生产直接用 Redisson
RLock lock = redissonClient.getLock("order:" + orderId);
lock.lock(30, TimeUnit.SECONDS);
try { /* 业务 */ } finally { lock.unlock(); }

要点:

  • 必须 NX + EX 原子设置(防止死锁);
  • 释放要校验 value(防止误删别人的锁),用 Lua;
  • 可重入(Redisson 内部 hash 计数)、自动续期(watchdog)。

Zookeeper 分布式锁 ​

text
创建临时顺序节点 /lock/lock_0000000001
判断自己是否是最小节点:
  是 → 拿到锁
  否 → Watch 前一个节点,等它删除后再判断

要点:

  • 临时节点:客户端会话断开自动删除,天然防死锁;
  • 顺序节点 + Watch 实现公平锁;
  • 强一致(ZAB 协议),无过期时间误删问题。

2. 对比 ​

对比项RedisZookeeper
一致性主从切换可能丢锁(AP 场景)强一致(CP)
性能高(内存、无重协商)较低(ZAB 同步、Watch)
死锁处理过期时间(可能提前释放/误删)会话超时自动删除临时节点
实现复杂度简单,Redisson 开箱即用相对复杂
可用性高(主从/集群,但锁语义弱)需要 ZK 集群,脑裂处理
适用高性能、允许极少概率锁失效强一致、锁可靠性优先

3. 怎么选 ​

  • 大部分互联网业务用 Redis/Redisson:性能好、实现简单,锁偶尔失效(极端网络/主从切换)可接受,配合幂等兜底;
  • 对一致性要求极高(如唯一资源的强互斥、分布式调度)用 ZK;
  • 还有 etcd(Raft)作为中间选择,云原生场景常用。

4. 高频追问 ​

  • "Redis 锁的 master 宕机丢锁怎么办":Redlock(多实例投票)争议较大,生产多用"主从 + 哨兵 + 幂等兜底";
  • "锁过期了业务还没执行完":Redisson watchdog 自动续期,或业务侧处理;
  • "为什么要校验 value 再释放":防止自己的锁已过期被别的线程拿走,自己 unlock 把别人的锁删了。

一句话总结 ​

Redis 锁(SETNX + Redisson)性能高、实现简单,适合大多数业务;Zookeeper 临时顺序节点强一致、天然防死锁,适合锁可靠性优先的场景;选型本质是"性能 vs 一致性"的取舍,配幂等兜底更稳。

基于 VitePress 重建