面试必备:分布式锁的实现方式(Redis vs. Zookeeper)
在分布式系统中,多个进程可能需要同时访问某个共享资源,比如多个用户同时下单扣减库存、多个任务调度系统争抢任务。这时候,我们需要一个 分布式锁 来保证同一时刻只有一个进程可以执行关键操作,防止数据不一致的问题。
这篇文章将带你了解:
- 如何用 Redis 实现分布式锁?
- 如何用 Zookeeper 实现分布式锁?
- Redis vs. Zookeeper,哪种方案更高效、更安全?
不管你是刚入门分布式系统,还是在准备技术面试,都能从这篇文章中快速掌握分布式锁的核心概念!
一、Redis 分布式锁
Redis 是单线程的,天然具备原子性,可以作为分布式锁的实现工具。最常见的方法是使用 SETNX
(set if not exists)命令。
1. 最简单的 Redis 分布式锁
SET resource_name my_random_value NX PX 30000
- NX:仅在 key 不存在时才创建(保证互斥性)
- PX 30000:锁的超时时间,30 秒后自动释放,防止死锁
2. 释放锁的正确方式
当一个进程完成任务后,需要释放锁。如果简单地 DEL key
,可能会误删别人的锁。正确做法是:
- 进程获取锁时,写入一个唯一的随机值(
my_random_value
) - 释放锁前,先检查 key 的值是否是自己的随机值
- 只有匹配时才删除 key,防止误删他人的锁
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
为什么要加随机值?
- 进程 A 加锁成功,执行任务超时 30 秒,锁自动释放
- 进程 B 重新获取锁
- 进程 A 执行完任务后,如果直接
DEL key
,会误删进程 B 的锁!- 用随机值判断,可以避免误删
3. Redis RedLock(官方推荐)
Redis 可能会因为主从复制延迟、节点故障导致锁的不安全性。RedLock 是 Redis 官方推荐的改进方案:
- 使用 5 个 Redis 实例
- 必须至少 3 个实例成功加锁,才算加锁成功
- 如果获取锁的时间过长,放弃加锁
- 加锁失败,删除所有已创建的锁
优点:提升容错能力
缺点:实现较复杂,需要多个 Redis 实例
二、Zookeeper 分布式锁
Zookeeper 的分布式锁利用了 临时节点(Ephemeral ZNode) 的特性。只要持有锁的进程崩溃,锁就自动释放,不会发生 Redis 那种锁丢失的问题。
1. 基本实现
- 进程尝试创建一个临时 ZNode
- 创建成功 → 说明获取到了锁
- 创建失败 → 说明锁被别人占用
- 进程可以监听 ZNode,等锁释放后再尝试获取
2. 进阶版:顺序临时节点
- 进程创建临时 + 顺序 ZNode(如
/lock/lock-0001
) - 多个进程排队,编号最小的进程获得锁
- 其他进程监听前一个节点,等待锁释放
- 一旦前一个节点删除,下一个进程自动获得锁
/lock/lock-0001 (获取到锁)
/lock/lock-0002 (监听 lock-0001)
/lock/lock-0003 (监听 lock-0002)
这样可以避免 “所有进程同时监听同一个锁” 造成的 惊群效应(Thundering Herd)。
三、Redis vs. Zookeeper:哪种分布式锁更好?
比较维度 | Redis 分布式锁 | Zookeeper 分布式锁 |
---|---|---|
锁的获取 | 需要不断轮询(消耗 CPU) | 失败后可监听,不占用资源 |
锁的释放 | 需要超时 + 额外逻辑防止误删 | 进程崩溃自动释放 |
一致性 | 可能因主从复制问题丢锁 | 强一致性,不会丢锁 |
实现难度 | 代码简单,但可能有死锁、误删 | 代码稍复杂,但模型清晰 |
性能 | 高性能(适用于高并发) | 性能较低(适用于高可靠性场景) |
总结:
- 高性能场景(如高并发秒杀):选择 Redis
- 高可靠性场景(如任务调度、数据库分布式事务):选择 Zookeeper
- 如果团队不熟悉 Zookeeper,优先用 Redis + RedLock
四、面试技巧
在面试中,如果被问到 “分布式锁的实现方式?”,你可以这样回答:
- 最常见的方法是 Redis 和 Zookeeper
- Redis 分布式锁:用
SETNX
,加 PX 过期时间,防止死锁 - Redis RedLock:使用 5 个 Redis 实例,提升容错性
- Zookeeper 分布式锁:基于临时 ZNode,进程崩溃锁自动释放
- 两者对比:Redis 高性能但可能丢锁,Zookeeper 可靠但性能较低
- 具体使用 Redis 还是 Zookeeper,要看业务场景!
这样不仅展现了你的技术深度,还能显示你的思考能力,提高面试通过率!🎯
五、总结
- 分布式锁 解决多个进程访问共享资源的问题
- Redis 实现分布式锁:
SETNX
+ PX 过期时间- 用 随机值 + Lua 脚本 防止误删锁
- RedLock 适用于高容错场景
- Zookeeper 实现分布式锁:
- 基于临时 ZNode
- 进程崩溃自动释放锁
- 基于顺序节点排队,防止惊群效应
- 选择 Redis 还是 Zookeeper?
- 高性能场景(如秒杀系统)→ Redis
- 高可靠性场景(如任务调度)→ Zookeeper
希望这篇文章能帮你在面试中自信回答分布式锁的问题!如果觉得有帮助,别忘了点赞 + 收藏!🔥 🚀