redis锁必须设过期时间,否则客户端崩溃或网络中断会导致锁永久残留,引发请求阻塞和超卖;官方推荐用set key value ex seconds nx原子命令,并通过唯一value+lua脚本校验防止误删。

Redis锁为什么必须设过期时间?
不设过期时间的 SET 锁,一旦客户端崩溃或网络中断,锁就永远卡在 Redis 里,后续所有请求都会被阻塞。超卖问题没解决,反而引发大面积请求堆积。Redis 官方推荐用 SET key value EX seconds NX 原子命令代替 SETNX + EXPIRE,避免两者非原子导致的锁无过期风险。
如何防止锁被误删(即“删了别人的锁”)?
加锁时用唯一随机值(如 UUID 或随机字符串)作为 value;释放锁必须用 Lua 脚本比对 value 再 DEL,否则 A 加的锁可能被 B 直接 DEL 掉。常见错误是用 GET 判断再 DEL——中间存在竞态窗口。
- 加锁:用
redis.set("lock:order:123", "uuid-abc", ex=10, nx=True) - 释放锁:执行 Lua 脚本
if redis.call("GET", KEYS[1]) == ARGV[1] then return redis.call("DEL", KEYS[1]) else return 0 end
超卖场景下,锁的持有时间怎么设才合理?
过期时间不是越长越安全。它必须大于业务逻辑最大耗时(比如扣库存+写 DB+发 MQ),但也不能远大于该耗时,否则故障恢复慢、锁残留久。实测建议:预估单次操作 P99 耗时 × 2,再向上取整到秒级(如 3s → 6s)。若业务耗时波动大,可动态计算并传入 EX 参数,但需确保不超过业务整体超时阈值。
Redlock 真的必要吗?大多数电商场景其实不用
单 Redis 实例 + 正确的过期+校验机制,已能解决 95% 的超卖。Redlock 在网络分区下也存在边界问题,且引入复杂性和延迟。除非你有跨机房多活、强一致性 SLA 要求,否则优先用单节点带过期的 Lua 安全锁。注意:主从切换期间可能丢锁,所以生产环境务必开启 Redis 的 min-replicas-to-write 1 和 min-replicas-max-lag 配置来降低风险。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











