Redis 分布式锁的正确实现
📺 配套视频
📝 知识点总结
分布式锁的三个核心要求
- 互斥性:同一时刻只有一个客户端持有锁
- 防死锁:持有锁的客户端崩溃后,锁能自动释放
- 防误删:只能释放自己加的锁,不能释放别人的
演进过程
| 版本 | 实现方式 | 问题 |
|---|---|---|
| V1 | SETNX key value | 没有过期时间,宕机死锁 |
| V2 | SETNX + EXPIRE | 两条命令非原子,中间宕机仍死锁 |
| V3 | SET key value EX 30 NX | 原子操作,但可能误删别人的锁 |
| V4 | value 存唯一标识 + Lua 脚本释放 | 基本可用 |
| V5 | Redisson(看门狗自动续期) | 生产推荐 |
Lua 脚本释放锁(V4)
-- 释放锁:只有持有者才能删除
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
Redisson 使用示例(V5 生产推荐)
RLock lock = redissonClient.getLock("order:lock:" + orderId);
try {
// 等待3秒,锁自动续期(看门狗机制,默认30秒续一次)
if (lock.tryLock(3, TimeUnit.SECONDS)) {
// 业务逻辑
processOrder(orderId);
}
} finally {
if (lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
Redisson 看门狗原理
- 加锁成功后启动一个定时任务(watchdog),每隔
lockWatchdogTimeout / 3(默认10秒)续期一次 - 客户端宕机 → 定时任务停止 → 锁到期自动释放 → 不会死锁
🔗 延伸阅读
- Nacos 源码深度解析 — 分布式系统中的服务发现与配置管理