Skip to content

Redis 并发与分布式

分布式锁是什么

分布式锁是在多个服务实例、多个进程之间共享的一把锁,用来保证同一时刻只有一个执行者处理某段临界区逻辑。

Redis 实现分布式锁的基本命令是:

bash
SET lock:order:1001 uniqueValue NX PX 30000

含义是:key 不存在时才设置成功,并设置 30 秒过期时间。NX 保证互斥,PX 防止服务宕机后死锁,uniqueValue 用于释放锁时校验身份。

释放锁不能直接 DEL,否则可能误删别人的锁。应该用 Lua 脚本先判断 value 是否匹配,匹配才删除。

lua
if redis.call("get", KEYS[1]) == ARGV[1] then
  return redis.call("del", KEYS[1])
else
  return 0
end

分布式锁怎么延长过期时间

如果业务执行时间可能超过锁 TTL,需要续期。常见做法是 watchdog:持锁线程还活着并且锁 value 没变时,后台定期延长过期时间。

续期也必须保证原子性,不能无条件 expire,否则可能给别人的锁续期。正确做法是用 Lua 判断 value 仍然是自己的,再执行 pexpire

Redisson 的分布式锁就内置了 watchdog。默认思路是:加锁成功后启动续期任务,业务完成释放锁;如果服务崩溃,续期停止,锁最终自然过期。

分布式锁还要注意:

  • 锁粒度不能太粗,否则吞吐低。
  • TTL 不能太短,否则业务未完成锁已过期。
  • 加锁失败要明确是重试、排队还是快速失败。
  • Redis 主从异步复制下,极端故障切换可能破坏锁安全性;强一致锁场景要考虑 ZooKeeper、etcd 或数据库锁。