Redisson 实现分布式锁原理
Redisson实现分布式锁
有关Redisson作为实现分布式锁,总的分3大模块来讲。
1、Redisson实现分布式锁原理
2、Redisson实现分布式锁的源码解析
3、Redisson实现分布式锁的项目代码(可以用于实际项目中)
本文只介绍Redisson如何实现分布式锁的原理。
一、高效分布式锁
当我们在设计分布式锁的时候,我们应该考虑分布式锁至少要满足的一些条件,同时考虑如何高效的设计分布式锁,这里我认为以下几点是必须要考虑的。
1、互斥
在分布式高并发的条件下,我们最需要保证,同一时刻只能有一个线程获得锁,这是最基本的一点。
2、防止死锁
在分布式高并发的条件下,比如有个线程获得锁的同时,还没有来得及去释放锁,就因为系统故障或者其它原因使它无法执行释放锁的命令,导致其它线程都无法获得锁,造成死锁。
所以分布式非常有必要设置锁的 有效时间
,确保系统出现故障后,在一定时间内能够主动去释放锁,避免造成死锁的情况。
3、性能
对于访问量大的共享资源,需要考虑减少锁等待的时间,避免导致大量线程阻塞。
所以在锁的设计时,需要考虑两点。
1、 锁的颗粒度要尽量小
。比如你要通过锁来减库存,那这个锁的名称你可以设置成是商品的ID,而不是任取名称。这样这个锁只对当前商品有效,锁的颗粒度小。
2、 锁的范围尽量要小
。比如只要锁2行代码就可以解决问题的,那就不要去锁10行代码了。
4、重入
我们知道ReentrantLock是可重入锁,那它的特点就是:同一个线程可以重复拿到同一个资源的锁。重入锁非常有利于资源的高效利用。关于这点之后会做演示。
针对以上Redisson都能很好的满足,下面就来分析下它。
二、Redisson原理分析
为了更好的理解分布式锁的原理,我这边自己画张图通过这张图来分析。
1、加锁机制
线程去获取锁,获取成功: 执行lua脚本,保存数据到redis数据库。
线程去获取锁,获取失败: 一直通过while循环尝试获取锁,获取成功后,执行lua脚本,保存数据到redis数据库。
2、watch dog自动延期机制
最常见的使用方法:
RLock lock = redisson.getLock("my-lock");
// 最常见的使用方法
lock.lock();
解释说明
使用基本锁以后,redisson使用了自动续期,如果业务超长,运行期间自动续上30s,不用担心业务时间长,锁自动过期被删掉。
大家都知道,如果负责储存这个分布式锁的Redisson节点宕机以后,而且这个锁正好处于锁住的状态时,这个锁会出现锁死的状态。为了避免这种情况的发生,Redisson内部提供了一个监控锁的看门狗,它的作用是在Redisson实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗的检查锁的超时时间是30秒钟,也可以通过修改Config.lockWatchdogTimeout来另行指定。
另外Redisson还通过加锁的方法提供了leaseTime的参数来指定加锁的时间。超过这个时间后锁便自动解开了。
// 加锁以后10秒钟自动解锁
// 无需调用unlock方法手动解锁
lock.lock(10, TimeUnit.SECONDS);// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {try {...} finally {lock.unlock();}
}
看门狗这里我自己的理解就是:
在一个分布式环境下,假如一个线程获得锁后,突然服务器宕机了,那么这个时候在一定时间后这个锁会自动释放,你也可以设置锁的有效时间(不设置默认30秒),这样的目的主要是防止死锁的发生。
但在实际开发中会有下面一种情况:
//设置锁1秒过去redissonLock.lock("redisson", 1);/*** 业务逻辑需要咨询2秒*/redissonLock.release("redisson");/*** 线程1 进来获得锁后,线程一切正常并没有宕机,但它的业务逻辑需要执行2秒,这就会有个问题,在 线程1 执行1秒后,这个锁就自动过期了,* 那么这个时候 线程2 进来了。那么就存在 线程1和线程2 同时在这段业务逻辑里执行代码,这当然是不合理的。* 而且如果是这种情况,那么在解锁时系统会抛异常,因为解锁和加锁已经不是同一线程了,具体后面代码演示。*/
所以这个时候 看门狗
就出现了,它的作用就是 线程1 业务还没有执行完,时间就过了,线程1 还想持有锁的话,就会启动一个watch
dog后台线程,不断的延长锁key的生存时间。
注意
正常这个看门狗线程是不启动的,还有就是这个看门狗启动后对整体性能也会有一定影响,所以不建议开启看门狗。
3、为啥要用lua脚本呢?
这个不用多说,主要是如果你的业务逻辑复杂的话,通过封装在lua脚本中发送给redis,而且redis是单线程的,这样就保证这段复杂业务逻辑执行的
原子性 。
4、可重入加锁机制
Redisson可以实现可重入加锁机制的原因,我觉得跟两点有关:
1、Redis存储锁的数据类型是 Hash类型2、Hash数据类型的key值包含了当前线程信息。
下面是redis存储的数据
这里表面数据类型是Hash类型,Hash类型相当于我们java的 <key,<key1,value>>
类型,这里key是指 'redisson'
它的有效期还有9秒,我们再来看里们的key1值为 078e44a3-5f95-4e24-b6aa-80684655a15a:45
它的组成是:
guid + 当前线程的ID。后面的value是就和可重入加锁有关。
举图说明
上面这图的意思就是可重入锁的机制,它最大的优点就是相同线程不需要在等待锁,而是可以直接进行相应操作。
5、Redis分布式锁的缺点
Redis分布式锁会有个缺陷,就是在Redis哨兵模式下:
客户端1
对某个 master节点
写入了redisson锁,此时会异步复制给对应的 slave节点。但是这个过程中一旦发生
master节点宕机,主备切换,slave节点从变为了 master节点。
这时 客户端2
来尝试加锁的时候,在新的master节点上也能加锁,此时就会导致多个客户端对同一个分布式锁完成了加锁。
这时系统在业务语义上一定会出现问题, 导致各种脏数据的产生 。
缺陷
在哨兵模式或者主从模式下,如果 master实例宕机的时候,可能导致多个客户端同时完成加锁。
关于看门狗死锁:
就是上锁时会有个过期时间,然后看门狗其实就是个定时任务,在每隔1/3默认时间时也就是10s执行一次,
然后把过期时间蓄满,所以在业务完成执行完成之前,锁不会自动过期,而业务完成之后锁也会自动过期,有个过期时间自然也就解决了死锁
通过源码分析我们知道,默认情况下,加锁的时间是30秒.如果加锁的业务没有执行完,那么到 30-10 = 20秒的时候,就会进行一次续期,把锁重置成30秒.那这个时候可能又有同学问了,那业务的机器万一宕机了呢?宕机了定时任务跑不了,就续不了期,那自然30秒之后锁就解开了呗.
Redisson 实现分布式锁原理相关推荐
- Redisson实现分布式锁原理
Redisson实现分布式锁原理 一.高效分布式锁 当我们在设计分布式锁的时候,我们应该考虑分布式锁至少要满足的一些条件,同时考虑如何高效的设计分布式锁,这里我认为以下几点是必须要考虑的. 1.互斥 ...
- 超详细的Redisson实现分布式锁原理解析
for update select column from table where column = ... for update 在select的sql上加上for update会对此记录加上行级锁 ...
- 22-09-20 西安 谷粒商城(04)Redisson做分布式锁、布隆过滤器、AOP赋能、自定义注解做缓存管理、秒杀测试
Redisson 1.Redisson做分布式锁 分布式锁主流的实现方案: 基于数据库实现分布式锁 基于缓存(Redis),性能最高 基于Zookeeper,可靠性最高 Redisson是一个在Re ...
- Redisson实现分布式锁(3)—项目落地实现
Redisson实现分布式锁(3)-项目落地实现 有关Redisson实现分布式锁前面写了两篇博客作为该项目落地的铺垫. 1.Redisson实现分布式锁(1)-原理 2.Redisson实现分布式锁 ...
- SpringBoot+Redisson实现分布式锁
目录 项目结构 pom.xml application.yml RedissonProperties RedissonAutoConfiguration DistributedLocker Redis ...
- Redission 分布式锁原理
Reddission 分布式锁原理 总结: 使用无参的tryLock()方法时,redisson会自动添加一个定时任务,定时刷新锁的失效时间,如果unlock时失败,则会出现该锁一直不释放的情况, 因 ...
- Redis分布式锁原理(一)——redis分布式锁需要注意的问题
下一篇:Redis分布式锁原理(二)--Redisson分布式锁源码浅析 虽然目前Redisson框架已经帮我们封装好了分布式锁的实现逻辑,我们可以直接像调用本地锁一样使用即可,但本文并不直接剖析Re ...
- redis和redission分布式锁原理及区别
redis和redission分布式锁原理及区别 我最近做租车项目,在处理分布式时用到分布式锁,我发现很多同事都在网上找分布式锁的资料,但是看的资料都不是很全,所以在这里我谈谈自己的分布式锁理解. 结 ...
- api 创建zookeeper客户端_zookeeper分布式锁原理及实现
前言 本文介绍下 zookeeper方式 实现分布式锁 原理简介 zookeeper实现分布式锁的原理就是多个节点同时在一个指定的节点下面创建临时会话顺序节点,谁创建的节点序号最小,谁就获得了锁,并且 ...
最新文章
- notification antd 弹窗使用示例
- Linux redhat 5.4上安装MYDNS
- 在centos 下安装配置基于gitosis 的git 服务
- 站在吃货的角度来解释那些和微服务有关的名词
- 设计模式--桥(Bridge)模式
- VS2017配置opencv教程(图文详解)
- 征战蓝桥 —— 2018年第九届 —— C/C++B组第3题——乘积尾零
- 51nod-有限背包计数问题【dp】
- Android学习笔记(三)——Button之圆角、按压效果、点击事件
- 7天学完Java基础之4/7
- C#【Thread】Interlocked 轻量级锁
- excel工具箱_Excel工具箱15.54安装教程
- Java学习笔记(五)——数组
- 从零实现深度学习框架——Softmax回归简介
- navicat premium使用教程 Navicat Premium mac的基本使用
- ECSHOP4.0 H5端源码运行环境安装
- coreseek添加新词库
- php递归返回值只有第一次的结果,php递归函数出现返回值问题的解决
- iOS之healthKit
- Echarts X轴内容过长自动隐藏,鼠标移动上去显示全部