Redisson(4)分布式锁之RedLock

Redis官方文档探讨了使用Redis实现分布式锁时可能遇到的问题,包括主节点故障导致锁丢失和锁超时的安全隐患。解决方案是通过设置随机value确保删除操作的准确性,但仍有在业务执行超时时线程间竞争锁的风险。Redisson通过管理多个锁并采用循环加锁策略,解决了单点故障和锁超时问题,提供更健壮的分布式锁实现。
摘要由CSDN通过智能技术生成

 Redis实现分布式锁的官方文档介绍

Redis的官方文档对用Redis分布式锁的难点以及解决方案的考虑做了一些说明,具体内容参见:/docs/reference/patterns/distributed-locks/,译文参考:《Redis官方文档》用Redis构建分布式锁 | 并发编程网 – ifeve.com

场景一:

保存锁的Redis的master节点挂了。这里不是说有slave就没问题了,因为Redis的数据复制功能(replication)是异步的,存在这样的可能,线程1获取到锁了,该锁在从master复制到slave之前,master挂掉了,然后slave提升为了master,这个时候线程2从新的master节点上是可以获取到锁的,之前的锁丢失了,这样会导致安全问题。

场景二:

对于锁“lock123”(名字随便取的),线程一获取到锁,设置过期时间为30s,但是真正业务执行时间超过了30s,比如说40s。在32s的时候线程二尝试获取锁,并且成功了,因为这个锁的超时时间是30s,在32s的时候,该锁已经失效了。当40s的时候,线程一业务执行完毕,这个时候尝试去释放锁,即删除锁,很不幸,这个时候线程二锁持有的锁会被线程一误删掉,因为它们的key相同。

解决方案:

set操作的时候,设置一个random value作为该key的value,在解锁的时候,判断当前锁的value和该value是相同的,这样才可以执行删除操作,就可以解决上面场景中的误删问题了。但是其实并不完美,因为在第一个线程执行完任务之前,线程二不应该获取锁,但是该锁的过期时间比业务执行时间短,从而导致了线程二仍然获取到了锁。

Redisson的解决方案

在redis的文档中提到了一个算法,如果按照这个算法来实现分布式锁的话,可以解决之前提到的那些问题。

Redisson的实现在RedissonMultiLock中,核心算法在tryLock方法中:

这里管理了多个锁,为的就是解决某一个Redis节点上保存的锁因为该Redis节点出现问题而导致锁不可用的情况。for循环对每个锁进行尝试加锁操作,这里有两种情况:

①如果获取锁成功,那么就将当前锁添加到已获取锁的队列中去

②如果加锁失败,那么判断当前成功的锁的个数是否达标,如果达标,那么跳出循环。如果不达标,那么失败限制计数减一(因为上面再次循环成功的次数有可能加一,所以这里失败限制要减一)。然后检查是否已经超时,如果超时,说明在超时限定时间内没有获取到锁,即获取锁失败,这时释放所有已经成功加锁的所有锁。如果加锁成功的话,那么给所有已经加锁成功的锁设置超时时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值