060调度模块Redisson vs Redis 原生锁:两种分布式锁实现深度对比
本文章代码: gitee , gitcode , github
摘要
同一个调度框架内同时提供了基于 Redis 原生命令的锁服务和基于 Redisson 的锁服务。本文从功能特性、使用复杂度、可靠性角度对比两者的差异,并给出选型建议。
1. 锁获取方式
| 框架 | 非阻塞尝试 | 阻塞等待 | 可重入 |
|---|---|---|---|
RedisLockService |
❌(仅 try once) | ❌ | ❌ |
RedissonReentrantLockService |
✅ tryLock(waitTime) |
❌ | ✅ |
RedissonBlockLockService |
❌ | ✅ lock() 永久阻塞 |
✅ |
- Redis 原生锁 :
SET NX PX原子操作,仅尝试一次,失败立即返回。适合对延迟敏感且锁竞争不激烈的场景。 - Redisson 可重入锁:支持等待超时,可重入,解决同一线程多次获取锁的死锁问题。
- Redisson 阻塞锁:会一直阻塞直到获取锁,适合必须确保执行的任务(但需警惕死等)。
2. 自动续期机制
- Redis 原生自动续期 :框架自己启动
ScheduledThreadPoolExecutor,每隔 5 秒执行 Lua 脚本续期。需要额外管理线程池生命周期,且续期不及时可能导致锁提前释放。 - Redisson 看门狗 :内置
netty定时任务,默认 30 秒检查一次,只要锁还被当前线程持有且任务未完成,自动续期。实现更健壮,无需手动管理。
3. 故障恢复
- Redis 原生:若持有锁的节点宕机,续期线程消失,锁会在原租期后自动释放,相对安全。
- Redisson:同样会过期释放,但看门狗在节点宕机后也会停止,锁最终过期释放。
4. 使用复杂度
- Redis 原生 :需要自己管理
RedisTemplate、Lua 脚本、续期线程池,代码量较大但依赖少。 - Redisson :只需注入
RedissonClient,调用getLock()即可,API 更友好,但引入额外依赖。
5. 选型建议
| 场景 | 推荐方案 |
|---|---|
| 轻量应用,不想引入 Redisson | RedisLockService + 固定租期或自动续期 |
| 需要可重入、看门狗自动续期 | RedissonReentrantLockService |
| 任务必须执行,允许阻塞等待 | RedissonBlockLockService(注意设置合理的租期避免死锁) |