Redis分布式锁的实现原理
作为后端工程师,分布式锁是面试必考题。今天咱们就深挖Redis分布式锁的实现原理,帮你轻松应对面试提问!

📦 一、为什么要用Redis分布式锁?
在分布式系统中,多个服务实例可能同时操作共享资源(比如扣减库存)。本地锁(如Java的synchronized)只能控制单个JVM内的线程,跨服务就失效了。这时就需要Redis分布式锁实现跨进程互斥。
核心目标:保证在任意时刻,只有一个客户端能持有锁!
🧩 二、基础实现:SETNX + EXPIRE
最简单的方式是利用Redis的两个命令:
SETNX key value:当key不存在时设置值(返回1),存在则不设置(返回0)。这步就是争抢Redis分布式锁。EXPIRE key seconds:给key设置过期时间,防止客户端崩溃导致锁永远不释放。
# 伪命令示例
SETNX lock:order:1234 client1 # 尝试加锁
EXPIRE lock:order:1234 30 # 设置30秒过期
⚠️ 致命缺陷:SETNX和EXPIRE是两条独立命令,非原子操作!如果在SETNX成功后客户端崩溃,EXPIRE未执行,锁就变“永不过期”了!
🔒 三、原子操作:SET命令救场
Redis 2.6.12后,SET命令支持NX(Not eXist)和EX/PX(过期时间)参数,完美解决原子性问题:
SET lock:order:1234 client1 NX EX 30
这条命令原子性地完成了:“当lock:order:1234不存在时,设置值为client1,并设置30秒过期时间”。这才是Redis分布式锁的安全基础!
🔄 四、释放锁的坑:防止误删
你以为DEL key就完事了?考虑这个场景:
- 客户端A获取锁(过期30秒)。
- A因GC停顿导致锁过期释放。
- 客户端B获取了该锁。
- A恢复后执行
DEL,删除了B的锁!
解决方案:解锁时验证锁的值(客户端标识)是否匹配!使用Lua脚本保证原子性:
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end
⏱️ 五、锁续期(Watch Dog)
如果业务执行时间超过锁的过期时间怎么办?锁可能被其他客户端获取,导致数据错乱!
续期机制:获取锁成功后,启动一个后台线程(看门狗),定期(比如每10秒)检查锁是否仍持有并重置过期时间(如重置为30秒)。Redisson等库提供了现成实现。

🌐 六、高可用方案:Redlock算法
单节点Redis宕机怎么办?Redis作者提出了Redlock算法(分布式锁的分布式实现):
- 获取当前时间(start_time)。
- 依次尝试向N(通常>=5)个独立的Redis主节点发送
SET key random_value NX PX T命令。 - 计算耗时:如果从大多数(N/2+1)节点获取锁成功,且总耗时 < 锁有效时间(T),则认为获取成功。锁的实际有效时间 = T - 总耗时。
- 如果失败(未获多数锁或超时),则向所有节点发送解锁命令。
📌 关键点:独立部署、N/2+1多数派、时钟依赖性强(建议使用NTP同步)。
💎 总结核心要点
- Redis分布式锁基础靠
SET key value NX EX原子命令。 - 释放锁需验证客户端标识(防误删),推荐用Lua脚本。
- 长任务需锁续期(Watch Dog机制)。
- 生产环境追求高可用可考虑Redlock(注意其争议和复杂性)。
- 评估好锁粒度和过期时间!
📌 面试资源利器:
备战2025年Java面试?这份Java面试宝典助你通关:
🔗 链接: https://pan.baidu.com/s/1RUVf75gmDVsg8MQp4yRChg?pwd=9b3g 提取码: 9b3g
👉 温馨小提示:如果你计划购买面试鸭会员,记得通过 面试鸭返利网 下单,可额外获得 25元返利 哦!省心又实惠!



