项目里哪些业务用过 Redis 分布式锁?锁过期、误删和主从切换问题怎么处理?
我的判断
分布式锁用于跨实例互斥,但必须有唯一持有者标识、原子释放、租期和业务侧幂等;不能把正确性全押在锁上。
我们只在确实需要跨实例串行、且更合适的数据约束不存在时使用,例如同一商户的结算任务。获取锁用 SET key token NX PX lease,token 每次请求唯一;释放通过 Lua 先比 token 再删除,防止自己的锁过期后误删新持有者的锁。
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
end
return 0
任务可能超过租期时要么把临界区变短,要么使用成熟客户端的看门狗;续租失败后不能假设自己仍持锁。主从异步复制下,主节点刚写锁就宕机可能让新主看不到锁,所以高价值写入还要用数据库唯一约束、版本号或 fencing token 拒绝旧持有者。
业务操作必须幂等,锁获取失败也要有限重试并带抖动。很多“防重复下单”直接用唯一索引更可靠,不需要先加一把分布式锁。
容易答偏踩坑误区
- 释放时直接 DEL。 可能删除已经属于别人的新锁。
- 租期无限长。 进程崩溃后资源永久不可用。
- 拿到锁就认为一定独占到结束。 GC 停顿、网络分区和主从切换都会破坏这个假设。