分布式锁就是在单体锁的基础上考虑了分布式环境的问题。那实现分布式锁,就得先实现单体锁。单体锁的几个特性:
1、互斥性 2、可重入 3、阻塞线程
互斥性:用redis的原子性就可以实现,setnx(哈希结构同理)
可重入性:redis用map结构,key记录当前线程id+uuid,value记录重入次数
阻塞:CAS自旋抢锁(或者利用redis的发布订阅机制,但是阻塞是一样的)
然后考虑分布式环境的问题
1、锁的释放和续期:看门狗机制(守护线程机制)
2、分布式的数据一致性问题:联锁机制 联锁机制的问题:受网络波动较大,也有问题。
1. Redis 分布式锁的原子性保障
- SET NX 命令:一个线程拿到锁,另一个线程拿不到锁就不能往下走,这是锁的互斥性。通过
SET key value NX EX expire实现原子性加锁(只有 key 不存在时才设置),单命令天然原子性。 - LUA 脚本:多步骤操作(如加锁+续期)需用 Lua 脚本保证原子性,避免命令间穿插导致的数据不一致。
2. 锁的自动释放与看门狗机制
- 过期时间:锁必须设置过期时间,防止业务异常导致死锁。
- 看门狗(Watchdog):业务执行期间定时续期锁(如每 10s 延长过期时间),避免锁提前失效。
- 守护线程:看门狗设为守护线程,业务线程挂掉时JVM自动终止守护线程,防止锁永久占用。
3. 可重入锁的设计
- Java的计数器机制:
synchronized可重入性通过 对象头(Mark Word) 和 锁计数器 实现。- AQS 通过 状态变量(state) 和 当前持有线程 实现可重入性。
- Redission的计数器机制:同一线程多次获取锁时,用 Redis 哈希结构(如
HINCRBY)要锁的东西为KEY,线程id+UUID为FIELD,重入次数为VALUE,记录重入次数,解锁时递减计数器,归零后释放锁。 - 线程唯一标识:结合线程 ID + UUID 作为哈希字段,避免多线程冲突。
4. 可重入锁阻塞的实现
- Java的方案自旋重试:未抢到锁的线程循环尝试加锁(如
while (true)),直到成功或超时。 - synchronized
- 轻量级锁阶段:线程在用户态通过 CAS 自旋短暂尝试获取锁,避免频繁切换到内核态。自旋次数 由 JVM 自适应调整,若自旋失败则锁升级为重量级锁。
- 重量级锁阶段:未抢到锁的线程被放入 ObjectMonitor 的 _EntryList 队列,进入内核态阻塞。锁释放时,JVM 从队列中唤醒线程,但不保证唤醒顺序,允许新来的线程直接抢锁,体现非公平性。
- AQS
- 自旋 + 阻塞” 的混合策略。
- Redission的方案订阅发布机制:
- 如果线程未获取到锁,Redisson 会通过 Redis 的
Pub/Sub订阅锁的释放事件。 - 当锁被释放时(即其他线程释放锁),Redisson 会收到发布的通知。
- 收到通知后,Redisson 会再次尝试获取锁。
- 这种机制避免了传统自旋锁的高 CPU 消耗,同时提供了较高的性能和实时性
5. 主从架构下的锁丢失问题
- 主从同步延迟:主节点写入锁后宕机,一个从节点转从为主,但从节点未同步导致新主节点无锁数据,其他线程可能重复加锁。
- 解决方案:部署多主集群(如 Redis Cluster),加锁需所有主节点成功;或采用 RedLock 算法(半数以上节点成功)。
6. RedLock 算法的优缺点
要求REDIS要部署多个主节点,但是只需要半数以上加锁成功就行了,当某个线程加锁半数以上的节点成功了,那么其他线程就不可能再做到半数以上,加锁成功了,这就满足了互斥项
- 优点:通过多个独立 Redis 节点实现跨节点锁,容忍单点故障。
- 缺点:
- 需严格时钟同步(否则可能误判锁有效性)。
- Java 的 Stop-The-World GC 可能导致看门狗失效。
- 实现复杂,运维成本高,实际应用较少。
7. Redisson 的优化方案
- 底层实现:基于 Redis 哈希结构(非单纯
SET NX),支持可重入、公平锁等高级特性。 - 多主集群:通过 Redis Cluster 部署,结合 RedLock 算法提升可靠性。
8. 锁的设计原则
- 互斥性:同一时间仅一个客户端能持有锁。
- 无饥饿:避免线程无限等待(如设置超时时间)。
- 容错性:主从/多节点故障时仍能保证锁的有效性。
9. 常见陷阱
- 线程 ID 冲突:集群环境下线程 ID 可能重复,需拼接 UUID 保证唯一性。
- GC 暂停风险:JVM 的 Stop-The-World GC 可能导致看门狗失效,GC会暂停线程,导致看门狗无法对锁进行续期,然后锁就过期了
总结
Redis 分布式锁的核心是原子性 + 自动释放 + 容错机制,但实现细节需考虑主从同步、时钟偏差、GC 等复杂场景
172万+

被折叠的 条评论
为什么被折叠?



