八股文解析
分布式锁:Redis vs Zookeeper 怎么选?
分布式锁:Redis vs Zookeeper 怎么选?
一句话结论
- Redis:AP、性能高、实现简单,但极端场景可能丢锁
- Zookeeper:CP、可靠性高、有 watch 机制,但性能略低、运维重
- 互联网高并发:Redis 为主;金融/强一致:Zookeeper 或数据库悲观锁
面试标准答法
Redis 分布式锁
基础实现:
SET lock_key unique_value NX PX 30000NX:不存在才设置PX:过期时间,防死锁unique_value:标识持有者,释放时校验(Lua 脚本保证原子性)
问题与方案:
| 问题 | 方案 |
|---|---|
| 锁过期但业务没执行完 | 看门狗自动续期(Redisson) |
| 主从切换丢锁 | RedLock(多主节点),但有争议 |
| 误删他人锁 | 释放时校验 value,用 Lua 原子删除 |
Zookeeper 分布式锁
实现原理:
- 创建临时顺序节点:
/locks/lock-00000001 - 序号最小者获得锁
- 未获得者 watch 前一个节点,形成排队
优点:
- 临时节点:客户端宕机自动释放
- 顺序节点:公平锁,避免羊群效应
- watch 机制:无需轮询
缺点:
- 性能低于 Redis
- 需要维护 ZK 集群
对比表
| 维度 | Redis | Zookeeper |
|---|---|---|
| 一致性模型 | AP | CP |
| 性能 | 高 | 中 |
| 可靠性 | 中(主从切换风险) | 高 |
| 实现复杂度 | 低 | 中 |
| 运维成本 | 低 | 高 |
| 适用场景 | 高并发互联网 | 强一致金融/支付 |
常见追问
| 追问 | 要点 |
|---|---|
| RedLock 可靠吗? | Antirez 提出,Martin Kleppmann 质疑时钟跳变和 GC 导致锁失效;生产多数用单 Redis + 看门狗或 ZK |
| 为什么用 Lua 释放锁? | 保证「判断 value 是自己的」和「删除」原子执行 |
| 数据库能做分布式锁吗? | 可以:SELECT ... FOR UPDATE 或唯一索引,但性能差,一般不用 |
面试回答模板(30 秒版)
延伸准备
- 能手写 Redis 加锁/解锁 Lua 脚本
- 能解释 ZK 的羊群效应和如何避免
- 能对比 etcd 的
lease + revision分布式锁方案