Redisson 分布式锁学习笔记
一、基础版本对比
1. 不可重入 Redis 分布式锁
- 原理 :依靠
setnx互斥特性抢占锁;ex设置过期时间防止死锁;释放锁前校验线程标识,避免误删别人的锁。 - 缺点 :不可重入,同一个线程不能多次获取锁;没有自动重试;业务执行时间超过锁过期时间,会出现锁提前失效。
2. Redisson 可重入分布式锁(RLock)
- 三大核心能力
- 可重入:底层使用 Hash 结构,key 为锁名称,field 存线程 ID,value 记录重入计数。同一线程再次加锁,只把计数 + 1;释放锁计数 - 1,计数归 0 锁才真正删除。
- 可重试:使用 Redis 的 Pub/Sub 发布订阅,获取锁失败时线程订阅释放锁的消息,进入等待;别的线程释放锁后发送消息唤醒等待线程,自动重试抢锁,避免空轮询消耗 CPU。
- 超时续约(看门狗 WatchDog) :如果没有手动指定 leaseTime(锁过期时间),看门狗定时任务每
releaseTime/3时间就刷新锁过期时间。业务没执行完锁不会过期;一旦手动设置 leaseTime,看门狗直接失效。
- 流程梳理
- 尝试获取锁;拿到锁且未指定过期时间,启动看门狗续期。
- 获取锁失败:判断剩余等待时间,如果还有时间,订阅锁释放消息,阻塞等待唤醒;等待超时直接返回获取锁失败。
- 释放锁:计数减一,计数为 0 就删除锁,发送释放消息唤醒其他等待线程,关闭看门狗;释放失败记录异常。
- 主从一致性缺陷
Redis 主从模式下,锁写入 master 后,还没同步到 slave 节点,master 宕机,slave 晋升为新主库。锁数据丢失,其他客户端可以重新拿到锁,锁失效,出现并发安全问题。
3. Redisson MultiLock(联锁)
- 原理 :使用多个完全独立的 Redis 节点,必须在全部节点上都成功拿到锁,才算整体加锁成功。任意节点获取失败,全部节点一起释放锁。解决主从切换带来锁丢失的问题。
- 缺点:部署多套独立 Redis,运维成本高,实现逻辑复杂,性能下降。
二、面试核心问答(精简)
- 看门狗什么时候生效? 只有调用
lock()不传 leaseTime 才开启;指定了锁过期时间,看门狗不会启动,业务一定要在过期时间内完成。 - 可重入怎么实现? Hash 结构保存线程 ID + 计数器,同一线程加锁计数器自增,释放递减,归 0 锁删除。
- 获取锁失败如何等待,为什么不用 while 自旋? PubSub 订阅消息,线程阻塞等待通知;自旋会持续占用 CPU 资源。
- 主从模式锁安全漏洞怎么解决? 方案一:使用 MultiLock 多独立节点;方案二业务层面做幂等兜底。
- 联锁 MultiLock 和普通锁区别 普通锁只写主节点,依赖主从同步;MultiLock 要求所有独立节点全部加锁成功,牺牲性能换取更高一致性。