栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redisson分布式锁原理源码跟踪

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redisson分布式锁原理源码跟踪

Redisson

使用redis实现了分布式锁

分布式锁特性 互斥性

多个线程并发时,互相排斥,需要互斥则使用相同的key即可


getName为key名称,getLockName记录了线程

数据结构类似如下:

// redis key
{
  "线程id": 1
}

加锁成功脚本中都会返回nil,否则会返回剩余过期时间毫秒数

防死锁

防止加了锁,程序奔溃后没有释放锁的情况,导致其他线程永远无法成功加锁

通过给key添加过期时间来解决,但是如果过期时间到了,业务代码还没执行结束,这种情况redisson使用watch dog来解决,watch dog见下文

可重入

例如递归调用,如果当前线程加锁成功,当前线程递归调用该方法,应该可以成功加锁,而不是已经加了锁则报错加锁失败

lua脚本的第二个if中,判断了ARGV[2]即线程id存在情况下,对value进行次数增加1,所以可重入通过value记录了重入的次数

锁误删

即只能是加锁的人来解锁或者防死锁情况自动解锁

锁误删举例:

  1. 线程A进行加锁,并加锁成功,继续执行业务代码
  2. redis服务器宕机,并且没有持久化
  3. redis服务器恢复
  4. 线程B进行加锁,并加锁成功(此时Redis服务器中的锁事线程B加的)
  5. 线程A业务执行完成,执行锁释放,这事如果没有锁误删限制,那么线程A就会释放线程B加的锁

实现:


依旧通过线程id,作为hash的key的方式来防止误删

Watch Dog 看门狗

启动看门狗的代码如上图

使用commandExecutor.getConnectionManager().newTimeout的方式添加了一个延时任务

使用timer添加刚才定义的Task延时任务,看看timer是什么

HashedWheelTimer是netty提供的一个基于时间轮算法的延迟队列工具,用于延迟执行任务

时间轮算法

参考原文https://www.cnblogs.com/lihao007/p/10588072.html

HashedWheelTimer(
  					ThreadFactory threadFactory,
            long tickDuration, TimeUnit unit, int ticksPerWheel, boolean leakDetection,
            long maxPendingTimeouts)

threadFactory:线程工厂,用于创建工作线程,并且只会创建一个
tickDuration + unit:在每一个格子上的停留时间
ticksPerWheel:时间轮的格子数,每一个格子里都是一个Timeout任务队列bucket,双向链表结构
leakDetection:默认为true,开启泄漏检测
maxPendingTimeouts:最大挂起Timeouts任务数量

案例:

如图,一个轮分成8个bucket,每一个tick需要1秒,现在有一个延迟任务为延迟20秒后执行,则需要tick20次,1轮需要tick8次,则20/8 = 2轮,这个任务在添加到这个轮(wheel)中时,通过hash算法计算出应该放到哪一个目标bucket中并将计算出的2轮设置为该任务的剩余轮数,当指针每tick一次,落到这个bucket中时,会将bucket中的timeout(我们自己的延迟任务)的剩余轮数-1,当剩余轮数小于等于0的时候就执行该任务并从bucket中移除

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1003018.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号