Redis实现分布式锁的相关问题

为什么会出现分布式锁?

使用分布式锁的目的,无外乎就是保证同一时间只有一个客户端可以对共享资源进行操作。

引入分布式锁势必要引入一个第三方的基础设施,比如 MySQL,Redis,Zookeeper 等。

这些实现分布式锁的基础设施出问题了,也会影响业务,所以在使用分布式锁前可以考虑下是否可以不用加锁的方式实现?

不过这个不在本文的讨论范围内,本文假设加锁的需求是合理的,并且偏向于上面的第二种情况,为什么是偏向?因为不存在 100% 靠谱的分布式锁,看完下面的内容就明白了。

redis单实例中实现分布式锁的正确方式(原子性非常重要):

1.设置锁时,使用set命令,因为其包含了setnx,expire的功能,起到了原子操作的效果,给key设置随机值,并且只有在key不存在时才设置成功返回True,并且设置key的过期时间(最好用毫秒)

2.在获取锁后,并完成相关业务后,需要删除自己设置的锁(必须是只能删除自己设置的锁,不能删除他人设置的锁);

删除原因:保证服务器资源的高利用效率,不用等到锁自动过期才删除;

删除方法:最好使用Lua脚本删除(redis保证执行此脚本时不执行其他操作,保证操作的原子性),代码如下;逻辑是 先获取key,如果存在并且值是自己设置的就删除此key;否则就跳过;

在这里插入图片描述

多节点redis实现的分布式锁算法(RedLock):有效防止单点故障

假设有5个完全独立的redis主服务器

1.获取当前时间戳

2.client尝试按照顺序使用相同的key,value获取所有redis服务的锁,在获取锁的过程中的获取时间比锁过期时间短很多,这是为了不要过长时间等待已经关闭的redis服务。并且试着获取下一个redis实例。

比如:TTL为5s,设置获取锁最多用1s,所以如果一秒内无法获取锁,就放弃获取这个锁,从而尝试获取下个锁

3.client通过获取所有能获取的锁后的时间减去第一步的时间,这个时间差要小于TTL时间并且至少有3个redis实例成功获取锁,才算真正的获取锁成功

4.如果成功获取锁,则锁的真正有效时间是 TTL减去第三步的时间差 的时间;比如:TTL 是5s,获取所有锁用了2s,则真正锁有效时间为3s(其实应该再减去时钟漂移);

5.如果客户端由于某些原因获取锁失败,便会开始解锁所有redis实例;因为可能已经获取了小于3个锁,必须释放,否则影响其他client获取锁

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值