redis分布式锁

在实际业务场景中,如果业务中并发并不是很高,只用了单机的redis,为了防止突发流量可以使用单机的分布式锁防止对db层的冲击。如果想获得较高的安全性,并且可以接受不同进程共同持有锁的情况发生(由于redis主从复制是异步的),那么可以考虑使用redis主从实现故障转移。这里简单说一下加锁过程中出现故障转移的场景:
1、客户端A获取redis-master中的锁。
2、在将密钥写入传输到slave之前,主机崩溃。
3、slave晋升为master
4、客户端B获取相同的锁,而该资源的锁已经被客户端A所持有。此时出现了客户端A与客户端B共同持有锁的情况出现

之前在高并发情况下缓存相关问题一文中有提到解决 “缓存击穿“ 问题需要用到分布式锁并实现了单机版的分布式锁。

分布式锁需要满足的条件
  • 互斥:在任何给定时刻,只有一个客户端可以持有锁。
  • 无死锁:最终,即使锁定资源的客户端崩溃,也始终可以获得锁定。
  • 容错能力:只要大多数Redis节点都处于运行状态,客户端就可以获取和释放锁。
Redlock算法

我们假设我们有N个Redis节点。这些节点是完全独立的,我们将N = 5设置为一个合理的值,需要在不同的计算机或虚拟机上运行5个Redis主服务器,以确保它们将以大多数独立的方式发生故障。
为了获取锁,客户端执行以下操作:

1、以毫秒为单位获取当前时间。
2、尝试在所有N个redis中依次使用所有redis中相同的键名和随机值来获取锁定。在第2步中,在每个实例中设置锁时,客户端使用的超时时间小于总锁自动释放时间,以便获取该超时时间。例如,如果自动释放时间为10秒,则超时时间可能在5到50毫秒之间。这样可以防止客户端长时间与处于故障状态的Redis节点进行通信:如果某个实例不可用,我们应该尝试与下一个实例尽快进行通信。
3、客户端通过从当前时间中减去在步骤1中获得的时间戳,来计算获取锁所需的时间。当且仅当客户端能够在大多数实例(至少3个)中获取锁时, ,并且获取锁所花费的总时间小于锁有效时间,则认为已获取锁。
4、如果获取了锁,则将其有效时间视为初始有效时间减去经过的时间,如步骤3中所计算。
5、如果客户端由于某种原因(无法锁定N / 2 + 1个实例或有效时间为负数)而未能获得该锁,它将尝试解锁所有实例(即使它认为不是该实例)能够锁定)。

redlock的实现代码可参考官方示例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值