软件技术 · 知识点深化 · 分布式系统
分布式锁:Redis 实现与 RedLock 争议
单体用 synchronized 就够了,多机部署后同一个商品被两个 JVM 同时卖。分布式锁要在多进程间互斥。这一页讲透 Redis SETNX、锁超时、误删、Redisson 看门狗、以及 RedLock 争议。
① 怎么学(4 步走,约 65 分钟)
先建立直觉再抠细节,按这四步走最稳:
1看图建立直觉(10 分钟)
读②③:先在脑子里画出本课核心结构图。
2记完整体系(15 分钟)
读④:把对比表和公式看懂,不要急着背。
3跟例题走一遍(20 分钟)
精读⑤:看三个例题怎么用知识点解题。
4刷题纠错(剩余时间)
做⑦⑩,错题回⑥诊断。
本课小目标学完你要能:① 手写 Redis 分布式锁;② 解决锁超时和误删;③ 解释 Redisson 看门狗;④ 知道 RedLock 争议。
② 一图看懂:分布式锁实现全景
读法:中心是本课主题,四条分支展开核心维度,下方是典型应用与高频易错点。
③ 本质直觉:分布式锁就是"公共储物柜钥匙"
多台机器同时要操作共享资源(如库存),单机 synchronized 只管一个 JVM。分布式锁要让所有机器认同一把锁。
最朴素:SET lock:123 随机值 NX EX 30。NX 表示不存在才能设(互斥),EX 30 秒自动过期(防死锁)。
问题1 误删:A 拿锁执行 30 秒没完成,锁自动释放;B 拿到锁;A 执行完删锁,把 B 的锁删了。解法:锁值存唯一 UUID,删之前检查是不是自己的。
问题2 检查+删除非原子:GET 检查和 DEL 之间锁可能过期。解法:用 Lua 脚本把检查和删除合成原子操作。
问题3 业务太长锁过期:Redisson 看门狗自动续期,默认每 10 秒延长 30 秒,直到业务完成。
RedLock 争议Redis 作者提出多节点多数派加锁,但 Martin Kleppmann 质疑时钟漂移和网络分区问题。生产中单 Redis 主从+Redisson 看门狗通常够用,强一致场景用 ZK。
④ 完整知识体系
Redis 锁关键细节
| 问题 | 现象 | 解法 |
| 死锁 | 持锁进程宕机 | EX 自动过期 |
| 误删 | 删了别人的锁 | UUID 校验 |
| 非原子 | GET 和 DEL 之间锁过期 | Lua 脚本 |
| 业务过长 | 锁提前释放 | 看门狗续期 |
加锁SET lock_key uuid NX EX 30
解锁 Luaif redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end
Redisson 看门狗
加锁默认 30 秒,后台线程每 10 秒检查,如果线程还持有锁就续期到 30 秒。业务结束或宕机后不再续期,锁自动释放。
ZK 分布式锁
创建临时顺序节点,最小节点获得锁,其他节点监听前一个节点删除事件。好处:客户端宕机临时节点自动删除,不会死锁。
⑤ 应用场景与例题
例1 写一个加锁解锁
商品 123 秒杀。
加锁:SET lock:123 随机UUID NX EX 30。业务执行。解锁:Lua 脚本检查 UUID 一致再 DEL。
例2 A 执行慢,锁 30 秒到了,B 拿锁进来,A 删了 B 的锁
怎么避免?
锁值存 UUID,A 删锁前 GET 检查是不是自己的 UUID。不匹配不删。再配合 Lua 原子化。
例3 业务要执行 60 秒,锁 30 秒就过期了
用 Redisson 看门狗自动续期,不要硬编码过期时间。
做题心法加锁一行,解锁要 UUID+Lua,续期靠看门狗。
⑥ 高频错误诊断(4 条)
错误1:加锁不设过期时间持锁进程宕机,锁永远不释放,死锁。
错误2:锁值固定或不加 UUID误删别人的锁。
错误3:解锁先 GET 再 DEL两步非原子,中间可能过期。用 Lua。
错误4:业务很长还不续期锁提前释放,并发问题。用看门狗。
⑦ 考点真题演练(5 题)
考点分布
| 考法 | 出题形式 | 应对 |
| 加锁 | 问 NX EX 作用 | 互斥+自动过期 |
| 误删 | 问怎么避免 | UUID 校验 |
| 解锁 | 问为什么用 Lua | 原子化 |
| 续期 | 问看门狗作用 | 自动延长锁 |
真题basic1. Redis 加锁命令是?
真题mid2. 为了防止误删别人的锁,应该?
真题mid3. 为什么解锁要用 Lua 脚本?
真题hard4. Redisson 看门狗的作用是?
真题hard5. 对强一致要求极高的分布式锁,推荐?
⑧ 必背知识点卡
加锁:SET key uuid NX EX 30
UUID:标识锁归属,防误删
解锁:Lua 脚本原子检查+删除
看门狗:Redisson 自动续期
死锁:必须设过期时间
强一致:ZK 临时顺序节点
RedLock:多节点多数派,有争议
⑨ 动手输出:设计秒杀扣库存的分布式锁
场景:100 个商品,多实例部署,怎么防超卖?
① 加锁:SET lock:goods:123 UUID NX EX 30。
② 扣减:查库存、判断、扣减、下单。
③ 解锁:Lua 检查 UUID 再删。
④ 续期:用 Redisson 看门狗,业务慢不担心过期。
⑤ 兜底:数据库库存字段用乐观锁版本号兜底。
口述思路Redis 锁解决高并发互斥,数据库乐观锁兜底。
⑩ 分层练习(基础 + 中档 + 拔高)
▍基础 6 题
基础1为什么需要分布式锁?
多机部署,单机 synchronized 不够。
基础2NX 什么意思?
key 不存在才能设,保证互斥。
基础4为什么锁值用 UUID?
防止误删别人的锁。
基础5解锁为什么用 Lua?
检查+删除原子化。
基础6Redisson 看门狗干什么?
自动续期。
▍中档 5 题
中档1加锁不设过期时间会怎样?
持锁进程宕机,锁永久不释放。
中档2GET 检查后 DEL 有什么问题?
两步非原子,中间锁可能过期被别人拿。
中档3ZK 锁怎么实现?
临时顺序节点,最小节点持锁,监听前驱。
中档4RedLock 是什么?
多 Redis 节点多数派加锁算法。
中档5为什么 RedLock 有争议?
时钟漂移和网络分区可能导致互斥失效。
▍拔高 5 题
拔高1看门狗默认续期节奏?
锁 30 秒,每 10 秒续一次。
拔高2锁粒度怎么选?
锁商品 ID 而非全局,提高并发。
拔高3Redis 主从切换锁丢了怎么办?
主节点锁还没同步从节点就宕机,新主没有锁。RedLock 缓解但不完美。
拔高4数据库分布式锁怎么做?
SELECT ... FOR UPDATE 或唯一约束表,性能差但强一致。
拔高5分布式锁和乐观锁怎么选?
冲突少用乐观锁;冲突多用分布式锁。
⑪ 记忆口诀 + 7 天复习计划
三句口诀① SET NX EX 加锁,UUID 防误删。② Lua 解锁原子化,看门狗自动续。③ 强一致上 ZK,Redis 够用大多数场景。
| 天 | 任务 | 自检 |
| 第 1 天 | 读②③,写加解锁伪代码 | 命令正确 |
| 第 2 天 | 背问题表 + 基础 6 题 | 三问题记住 |
| 第 3 天 | 做中档 5 题,写 Lua 脚本 | 原子化 |
| 第 4 天 | 做拔高 5 题,对比 Redis/ZK | 取舍说清 |
| 第 5 天 | 做⑦真题 5 题 | 限时每题 2 分钟 |
| 第 6-7 天 | 合书口述误删怎么解 | 不看资料 |
← 返回软件技术总览