首页/数据/数据库速查/Redlock 算法与争议要点
Redis 运维与场景124 条

Redlock 算法与争议要点

Redlock 在 N 个相互独立的 Redis 主节点上依次用同一 key/token 加锁,多数(N/2+1)成功且总耗时小于 TTL 才算持锁;用于缓解单实例宕机导致锁服务不可用,但强一致场景存在争议。

数据库速查数据更新于 2026-10-13

Redlock 想解决什么

Redlock 在 N 个相互独立的 Redis 主节点上用同一个键与随机令牌依次加锁,只有在多数节点(N/2+1)加锁成功且总耗时小于锁的 TTL 时才认为持锁成功;释放时对每个节点执行只删自己令牌的脚本。它的目标不是强一致,而是避免单实例故障导致锁服务整体不可用。

基本信息

适用Redis 2.6.12 及以上,多实例独立部署场景
加锁条件成功节点数 ≥ N/2+1,且总耗时小于 TTL
释放方式Lua 脚本比对令牌后删除,避免误删他人锁
前提各节点时钟需 NTP 同步,网络延迟可控

加锁与释放流程

加锁与释放流程
# 对 5 个独立实例逐一加锁,成功数 >= 3 且总耗时小于 TTL 才算持锁成功
for h in 10.0.0.1 10.0.0.2 10.0.0.3 10.0.0.4 10.0.0.5; do
  redis-cli -h $h -p 6379 SET lock:job 6f1d2c4e NX PX 10000   # 令牌必须每次随机
 done
# 释放:只删除值等于自己令牌的键,避免误删新一轮持锁者的锁
#   if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) end
# 校验实际成功节点数,少于多数派要立刻释放已加上的锁

争议观点对照

视角核心论点实践含义
可用性优先单实例故障会让锁服务不可用,多实例多数派提升可用性适合高并发互斥但可容忍极少误判的场景
强一致优先依赖各节点时钟,GC 或网络暂停可让锁在实际过期后仍被使用强一致场景应改用共识系统或数据库事务
折中做法把 Redis 锁当高效互斥,而非绝对正确的锁下游用唯一索引或 fencing token 拒绝过期持有者的写入

落地要点

  • 节点要相互独立:同宿主、同交换机、同电源域都算不得独立
  • 令牌每次加锁随机生成,释放前比对,避免误删他人的锁
  • 锁外再设一层兜底:数据库唯一约束或版本号比较,防止过期写入
  • 设置合理的 TTL 并配合续期机制,业务执行时间要小于 TTL
  • 监控加锁成功率与耗时,多数派失败频繁说明网络或节点异常
把 Redlock 用在要求强一致的场景(例如资金扣减)风险很高:锁失效后的过期写入只有靠下游幂等或唯一约束才能拦住。
N 个 Redlock 节点若放在同一台宿主或同一台交换机下,多节点只是形式上的冗余,一挂全挂。

易错点

  • 节点时间漂移大:锁有效期判断失真,各节点必须开启 NTP 同步
  • 释放时不校验令牌:直接 DEL 会删掉别人新加的锁,造成互斥失效
  • 集中在同一宿主机部署多节点:单机故障就丢失多数派,冗余形同虚设
  • 强一致场景依赖 Redis 锁:应改用共识系统或数据库事务,并以唯一索引兜底

数据来源与参考

  • Redis 官方文档: Redlock
  • Martin Kleppmann: How to do distributed locking

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌