Redis分布式锁

1.如何使用Redis实现分布式锁?

主要是基于redis String 的setnx(set if not exit)原子性的特性实现的分布式锁,主要实现流程:

(1)首先进行一个循环条件判断,判断是否获取锁成功

(2)如果在缓存中存着这个数据,则结束循环条件判断直接返回结果

(3)否则就获取分布式锁,并设置一个过期时间防止加锁后宕机造成死锁,

  • (加锁的过程应该设置过期时间,否则程序获取到分布式锁宕机后,redis锁一直得不到释放会造成死锁)
  • 加锁过程其次应保证加锁过程和设置过期时间两个操作的原子性,因为程序获得锁后到设置完全过期时间这段时间宕机仍然会导致死锁
  • 使用当前线程的唯一标识作为分布式锁的键值,在删除锁的时候进行条件判断,防止线程在删锁的时候锁已经过期并且被其他线程获取造成误删
  • 上面也存在着误删的可能:在进入条件判断的一瞬间过期了,因此需要使用redis自己的脚本保证获取和删除操作的原子性
  • lock = ops.setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);

(4)如果获取锁失败,表示有其他线程正在使用锁,则等待一段时间后再次进入循环条件判断

(5)添加锁成功,则添加缓存然后再释放锁,最后返回数据。在释放锁的时候,使用使用LUA脚本保证获取和删除操作的原子性

2.介绍一下Redisson

Redisson 是一个在 Redis 基础上实现的 Java 驻内存数据网格,Redis 官网推荐使用 Redisson 作为分布式锁的解决方案。

  • 分布式锁:Redisson 提供了高效的分布式锁机制,它的所有加锁操作都是通过 Lua 脚本实现的,以保证操作的原子性
  • 看门狗机制:Redisson 基于看门狗机制来实现锁的自动续期,并防止宕机导致的死锁问题。当持有锁的客户端挂掉时,看门狗机制可以自动延长锁的持有时间,直到客户端恢复或超时。
  • 随机 Value 防误删:为了防止误删锁,Redisson 在对锁进行操作时会添加一个随机值,这个值在解锁时进行校验,以确保只有持有锁的客户端才能解锁。
  • 分布式 Java 常用对象:Redisson 不仅提供了分布式锁,还提供了诸如分布式集合、列表、映射、集合等常用 Java 对象的分布式实现。
  • 分布式服务:Redisson 还提供了许多分布式服务,包括分布式执行器、分布式计数器、分布式信号量、分布式锁和可重入锁等。

3.Redisson实现分布式锁的底层原理

(1)利用 Lua 脚本添加锁: Redisson 使用 Lua 脚本来保证操作的原子性;

  • 检查指定的锁Key是否存在;
  • 如果锁Key不存在,则设置锁Key并添加一个随机值(作为锁的唯一标识),并设置过期时间。
  • 如果锁Key已经存在,则返回失败。

(2)设置过期时间:默认情况下,Redisson 会为锁设置一个 30 秒的过期时间。这是为了防止客户端在持有锁期间崩溃或失联时,锁无法自动释放的问题。

(3)看门狗机制(WatchDog): 如果锁成功添加后,Redisson 会启动一个后台线程,定期检查锁的状态并续期。这是通过一个名为 "看门狗" 的机制来实现的:

  • 启动后台线程:在锁成功添加后,会启动一个后台线程来执行定期任务。
  • 定期任务:定期任务的执行周期大约是每 10 秒。这个任务会检查锁的过期时间,如果发现锁即将过期,则会重新设置过期时间,以防止锁被意外释放。
  • 续期操作:续期操作也是通过 Lua 脚本来实现的,确保续期操作的原子性。

(4)锁的释放:锁的释放也是通过 Lua 脚本来保证原子性,确保只有持有锁的客户端才能释放锁

8.4Redisson延期续锁

Redis中分布式锁对业务代码加锁,如果锁已经超时释放了,业务代码还没有执行完,可以通过redission看门狗完成续锁。

redission看门狗:

原理:业务加锁后启动一个看门狗,每隔一段时间检查一下,如果业务还持有锁key,那么就会不断的延长锁key的生存时间。

底层:将线程ID传入scheduleExpirationRenewal,然后在renewExpiration中创建定时任务,当线程持有锁的时间到了超时时间的1/3,就会通过定时任务中的renewExpirationAsync方法会通过Lua脚本为锁重新设置超时时间。

缺点:如果加锁的业务代码一直阻塞会导致这个锁一直被占用,无法释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值