Redis:Redisson看门狗续锁实现分布式锁的原理,及如何避坑

简介

在微服务场景下,为了防止多个进程及线程并发访问共享资源,如支付、下单等操作,会引入分布式锁来保证业务的并发安全。

Redis实现分布式的要求

1、互斥性;

防止多个进程及线程并发访问共享资源,使得资源串行访问操作。

2、设置锁过期时间;

为了防止锁悬挂,因为服务宕机,锁不释放问题,其它请求就无法获取锁。

3、自动续锁超时时间;

防止业务超时,超过锁过期时间自动释放,打破互斥性。

4、多条指令需要原子性;

lua脚本实现多个指令的加锁、解锁及续锁的原子性。

5、可重入性;

使用线程ID信息来保证同一线程请求锁的可重入性。

6、锁误删:自己把别人持有的锁删了;

多个客户端释放锁,如何防止自己删别人的或者别人删自己申请的锁。
获取锁之前,生成全局唯一id,判断是否是自己的id来避免。

7、锁等待:发布订阅机制通知等待锁的线程;

Redisson看门狗续锁实现分布式锁

以RedissonLock为例来分析

org.redisson.RedissonLock#tryLock()org.redisson.RedissonLock#unlock的实现。

tryLock方法调用分析:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

当锁超时时间为-1时,而且获取锁成功时,会启动看门狗定时任务自动续锁:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

每次续锁都要判断锁是否已经被释放,如果锁续期成功,自己再次调度自己,持续续锁操作。
为了保证原子性,用lua实现的原子性加锁操作:

lua加锁流程:

在这里插入图片描述

获取锁或锁重入,lua返回nil即Java的NULL值,如果获取锁失败,则返回锁的ttl时间。

根据返回值编码的设置:
在这里插入图片描述

RedisStrictCommand<Boolean> EVAL_NULL_BOOLEAN = new RedisStrictCommand<Boolean>("EVAL", new BooleanNullReplayConvertor());

返回NULL代码获取锁成功,后续开启续锁流程,否则返回false,表示获取锁失败。

unlock方法调用分析:

在这里插入图片描述

在这里插入图片描述

为了保证原子性,用lua实现的原子性释放锁操作:

释放锁流程:

在这里插入图片描述

发布订阅机制是为了通知调用org.redisson.RedissonLock#lock()方法等待锁的线程。

以上我们注意到,线程id信息携带了一个UUID随机数,是为了防止集群环境下,线程ID相同导致误删问题。

为了保证原子性,用lua实现的原子性续锁操作:
在这里插入图片描述

单实例锁VS集群锁

上面介绍的锁实现只能使用于单Redis实例,不支持Redis集群。并且如果锁所在的Redis实例挂掉了之后,采用哨兵模式进行主备切换。但由于Redis的主从复制(replication)是异步的,这可能会出现在数据同步过程中,master宕机,slave来不及同步数据就被选为master,从而数据丢失。

Redis的作者提供了红锁来实现集群锁,算法思想:https://redis.io/docs/reference/patterns/distributed-locks/;

Redisson看门狗续锁实现分布式锁-避坑

1、不要传递自定义锁超时时间,否则不会续锁;
2、加锁和释放锁要在同一个线程,否则影响可重入性逻辑判断,导致续锁、释放锁失败;
3、单实例宕机,主从切换问题导致锁丢失;

做了主从,或者使用了哨兵模式,基于redis的分布式锁的功能,就会出现问题。

如何避免:

1、使用红锁解决,当然红锁的实现也有自己的问题;
2、使用锁的Redis实例单独分配且业务隔离,尽量保证不宕机,监控此实例,及时响应报警处理;
3、业务实现幂等来兜底;

小结

在这里插入图片描述

Redis学习资料:

redis: https://url97.ctfile.com/d/36436597-51573286-ccffc3?p=1988 (访问密码:1988)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: Redis分布式锁Redission都是解决高并发中分布式锁的问题的方法。Redis分布式锁是通过使用K-V存储来判断是否拥有,避免了释放他人的的问题。当业务没有执行完毕但是已经过期时,可以采用守护线程的方式来定期检查是否过期,并延长的过期时间,也就是的续期机制。而Redission是一种实现分布式锁的解决方案,它首先获取,然后尝试加,加成功后执行业务逻辑,最后释放Redission解决了Redis实现分布式锁中的过期和释放他人的问题,通过内部机制和看门狗机制来保证的有效性。然而,Redission在Redis主从架构下存在高一致性问题,解决高一致性问题可以使用红锁或者zk,但这可能会牺牲高可用性。总的来说,Redis分布式锁Redission都是解决高并发中分布式锁的方法,但需要根据具体情况选择合适的方案。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [RedisRedission两种方式实现分布](https://blog.csdn.net/weixin_45150104/article/details/125131846)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值