分布式锁的实现

分布式锁就是在单体锁的基础上考虑了分布式环境的问题。那实现分布式锁,就得先实现单体锁。单体锁的几个特性:

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 等复杂场景

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值