Redis之红锁

Redis Redlock是一种分布式锁实现,通过在多个独立的Redis实例上获取锁来提高可靠性。客户端尝试在所有实例中顺序加锁,如果能在大多数(N/2+1)实例上成功并保证总耗时小于锁的有效时间,则认为获取锁成功。在失败时,会尽快释放已获取的锁并进行重试。释放锁时,需在所有实例上解锁,无论是否认为已成功加锁。
摘要由CSDN通过智能技术生成

官方Redlock链接地址:https://redis.io/topics/distlock

下面是关于官网上redlock的介绍

红锁算法

在该算法的分布式版本中,我们假设有N个Redis masters。这些节点是完全独立的,所以我们不使用复制或任何其他隐式协调系统。我们已经描述了如何在单个实例中安全地获取和释放锁。我们想当然地认为,算法将使用这种方法在单个实例中获取和释放锁。在我们的示例中,我们设置了N=5,这是一个合理的值,因此我们需要在不同的计算机或虚拟机上运行5个Redis主机,以确保它们以基本独立的方式失败。

为了获取锁,客户端执行以下操作:

它以毫秒为单位获取当前时间。

它尝试在所有N个实例中顺序获取锁,在所有实例中使用相同的密钥名和随机值。在步骤2中,当在每个实例中设置锁时,客户端使用一个超时,该超时与锁自动释放的总时间相比很小,以便获取它。例如,如果自动释放时间为10秒,则超时时间可能在~5-50毫秒范围内。这可以防止客户端在尝试与已关闭的Redis节点通话时长时间处于阻塞状态:如果某个实例不可用,我们应该尽快尝试与下一个实例通话。

客户端通过从当前时间中减去在步骤1中获得的时间戳来计算获取锁所用的时间。如果且仅当客户端能够在大多数实例(至少3个)中获取锁,并且获取锁所用的总时间小于锁有效时间,则认为已获取锁。

如果获得了锁,其有效时间将被视为初始有效时间减去经过的时间,如步骤3中计算的。

如果客户端由于某种原因(无法锁定N/2+1实例或有效期为负)未能获取锁,它将尝试解锁所有实例(即使是它认为无法锁定的实例)。

算法是异步的吗?

该算法基于这样的假设:虽然进程之间没有同步时钟,但每个进程中的本地时间仍以大致相同的速率流动,与锁的自动释放时间相比,误差很小。这种假设与现实世界中的计算机非常相似:每台计算机都有一个本地时钟,我们通常可以依靠不同的计算机来产生一个很小的时钟漂移。

在这一点上,我们需要更好地指定互斥规则:只有持有锁的客户端在锁有效期内(如步骤3中获得的)终止其工作,减去一些时间(仅几毫秒,以补偿进程之间的时钟漂移),才能保证互斥规则。

有关需要有界时钟漂移的类似系统的更多信息,本文是一篇有趣的参考文献:RELATIES:一种有效的分布式文件缓存一致性容错机制。

失败后重试

当一个客户端无法获取锁时,它应该在随机延迟后重试,以便尝试取消多个试图同时获取同一资源锁的客户端的同步(这可能会导致无人获胜的分裂状态)。此外,在大多数Redis实例中,客户端尝试获取锁的速度越快,大脑分裂情况的窗口就越小(并且需要重试),因此理想情况下,客户端应该尝试使用多路复用同时向N个实例发送SET命令。

值得强调的是,对于未能获得大部分锁的客户来说,尽快释放(部分)获得的锁是多么重要,这样就不需要等待密钥到期才能再次获取锁(但是,如果发生网络分区,并且客户端不再能够与Redis实例通信,则在等待密钥到期时需要支付可用性罚款)。

释放锁

释放锁很简单,只需要在所有实例中释放锁,不管客户机是否认为自己能够成功锁定给定实例。

 简单总结一下就是:

1获取当前的时间(单位是毫秒)

2有效的避免了获取redis发生down机或超时造成的阻塞状态,我们设置获取锁的尝试时间远远小于锁的超时时间,当reids不可用时立刻与下一个redis进行通信。

3对集群的每个节点进行加锁,如果大多数(N/2+1)加锁成功了,则认为获取锁成功。

4如果锁获取成功了,锁的超时时间就是最初的锁超时时间减去获取锁的总耗时时间

5如果锁获取失败了,去尽快释放(部分)获得的锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值