当前位置: 首页 > news >正文

Redis系列---Redission分布式锁

文章目录

  • 类型
  • 原理
  • 使用
  • 看门狗
  • 与setNx比较

类型

使用Redission,lock的机制其实是使用了ttl,一直等ttl为0再get。无论是redission还是redis的setNx,只要是锁,都必须有加锁和释放锁两个动作,二者缺一不可,并且需要把释放锁放到final中,这样可以保证锁一定被释放。 lock和unlock必须搭配使用,缺一不可。
redission中常用的lock就两个,一个是lock一个是trylock。两者都是阻塞加锁, 前者会一直阻塞,相应的该方法不存在返回值,因为无意义;后者可以传入一个等待时间,等待时间内持续阻塞,相应的该方法存在返回值,因为要确认是否成功加了锁。根据业务场景自己判断使用哪种锁,二者其实相似,trylock就是lock的进阶,加了一个等待时间而已。

trylock:public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit)public boolean tryLock(long waitTime, TimeUnit unit)public boolean tryLock() lock:public void lock()public void lock(long leaseTime, TimeUnit unit) private void lock(long leaseTime, TimeUnit unit, boolean interruptibly)waitTime等待/阻塞时间,tryLock若没有则等同于lock;
leaseTime锁持续时间;
unit时间单位。
其实大部分的重载方法都是将参数少/无参的方法加了一些默认值,最后return参数最多的方法。 

原理

  • 如果没有指定leaseTime(加锁时长),则意味着让看门狗(守护线程,且该守护线程是连接级别,不是线程)管理锁的过期时间,该时间由配置文件控制,默认为30S,然后在过期时间的1/3时刻进行监听一次,线程还在则加时,加时也是走配置文件。
  • 如果指定了leaseTime,则意味着自己管理过期时间,看门狗不会介入,即不会自动续期,到了leaseTime之后,如果程序没有执行完毕,依旧会释放锁。此时,其他线程就可以继续对key加锁
  • 如果线程A加锁成功,线程B又来加锁,此时线程B会获取到线程A还有多少秒释放锁,然后线程B会通过semaphore信号量来等待一定的时间
  • 线程B在等待了一定的时间之后,会重新尝试进行加锁,加锁成功,就返回,如果失败,就重复3步

使用

  • 关于lock和trylock的使用,按场景需要进行抉择
  • 关于leaseTime是否指定,也就是说要不要使用看门狗控制过期时间,这个很难抉择, 各有利弊,如果可以自己估算业务时间,建议别用看门狗,因为看门狗存在失效或者死锁的可能,但是如果实在估算不出程序执行时间,只能冒险用看门狗了。

看门狗

Redisson中的看门狗(Watchdog)机制用于自动延长锁的持有时间,以防止锁在业务逻辑执行过程中过期。它的工作原理如下:

  • 锁续期:当一个线程获取锁后,Redisson会启动一个后台任务(看门狗),定期检查锁的持有时间,并在锁即将过期时自动延长锁的持有时间。
  • 自动释放:如果线程正常释放锁,看门狗会停止续期任务。如果线程异常退出,看门狗也会在锁过期后自动释放锁。

然而,虽然看门狗机制设计得很好,但在某些极端情况下,仍然可能出现死锁。以下是一些可能导致死锁的场景:

  • 资源竞争:在高并发环境下,多个线程竞争同一个锁,可能会导致某些线程长时间等待锁,从而增加死锁的风险。
  • 系统资源耗尽:如果系统资源(如线程池、内存)耗尽,可能会导致看门狗无法正常工作,从而引发死锁。
  • 网络问题:如果Redis服务器出现网络问题,导致看门狗无法及时续期锁,可能会导致锁过期,从而引发死锁。

为了避免这些潜在的死锁问题,可以采取以下措施:

  • 合理设置锁的超时时间:确保锁的超时时间足够长,以覆盖大部分业务逻辑的执行时间。
  • 监控和告警:监控系统的运行状态,及时发现和处理资源耗尽、网络问题等异常情况。
  • 优化业务逻辑:尽量减少锁的持有时间,避免长时间占用锁。

总结就是

  • Redisson中的看门狗机制通常不会导致死锁,但在高并发、资源耗尽或网络问题等极端情况下,仍然可能出现死锁。
  • 通过合理设置锁的超时时间、监控系统状态和优化业务逻辑,可以有效降低死锁的风险。

与setNx比较

在一定程度上redission比setNX更优秀,因为它的所有操作都是通过的lua脚本:

  • 先判断key是否存在,如果key不存在,就加锁,并且设置过期时间
  • 如果key已经存在,并且当前加锁的key是重入了,那就将key对应的加锁次数加1
  • 如果key已存在,并且当前加锁的key和线程和已加锁的不一样,无法重入,那就返回当前key的过期时间

http://www.mrgr.cn/news/30843.html

相关文章:

  • 【在Linux世界中追寻伟大的One Piece】多路转接epoll
  • 【大数据学习 | kafka高级部分】kafka的kraft集群
  • 【AI日记】24.11.11 多模态 RAG:和视频对话 | Multimodal RAG: Chat with Videos
  • Transformer模型中的位置编码介绍
  • [论文粗读][REALM: Retrieval-Augmented Language Model Pre-Training
  • emr上使用sparkrunner运行beam数据流水线
  • 深度学习激活函数
  • 力扣560 和为k的子数组 Java版本
  • CCRC-CDO首席数据官:未成年人首次上网年龄持续降低
  • vmware官网下载
  • 企业如何使用数据分析管理系统
  • 数据类型转换工具类(字符串和int、double、long等数字类型互相转换)
  • C#_封装详解
  • docker容器
  • PrintPreviewDialog控件里面,预览好了按下打印按钮触发什么事件
  • 【Python】探索 Boltons:Python 标准库的强力补充
  • 今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 9月20日,星期五
  • 各类域名之间有什么区别
  • 数据结构 hashmap
  • 【CTF Reverse】XCTF GFSJ1100 easyre-xctf Writeup(UPX壳+脱壳+反汇编+字符串搜索+小端存储)
  • 渗透测试常用工具(非常详细)从零基础入门到精通,看完这一篇就够了。
  • CST软件超表面---电容或变容二极管调焦反射镜
  • 什么是HTTP DDOS,如何防护
  • BERT推理显存爆满?7个实用技巧教你快速优化!显存优化的最佳实践指南
  • VSCode配置、创建ROS项目简单记录
  • PyTorch的特点