您现在的位置是:主页 > news > 泉州做网站设计/网页设计自学要多久
泉州做网站设计/网页设计自学要多久
admin2025/5/11 0:50:06【news】
简介泉州做网站设计,网页设计自学要多久,wordpress模板在哪个目录,电商的推广主要是做什么的Redisson1. 底层原理2. 详解2.1 加锁机制2.1.1 为啥要用lua脚本呢?2.1.2 这段lua脚本是什么意思呢?2.1.3 如何加锁呢2.2 锁互斥机制 (客户端2来尝试加锁)2.3 watch dog自动延期机制2.4 可重入加锁机制2.5 锁释放机制1. 底层原理 …
Redisson
- 1. 底层原理
- 2. 详解
- 2.1 加锁机制
- 2.1.1 为啥要用lua脚本呢?
- 2.1.2 这段lua脚本是什么意思呢?
- 2.1.3 如何加锁呢
- 2.2 锁互斥机制 (客户端2来尝试加锁)
- 2.3 watch dog自动延期机制
- 2.4 可重入加锁机制
- 2.5 锁释放机制
1. 底层原理
Redisson实现Redis分布式锁的底层原理
2. 详解
2.1 加锁机制
现在某个客户端要加锁。如果该客户端面对的是一个redis cluster集群,他首先会根据hash节点选择一台机器。这里注意,仅仅只是选择一台机器!这点很关键!
紧接着,就会发送一段lua脚本到redis上,那段lua脚本如下所示:
2.1.1 为啥要用lua脚本呢?
因为一大坨复杂的业务逻辑,可以通过封装在lua脚本中发送给redis,保证这段复杂业务逻辑执行的原子性。
2.1.2 这段lua脚本是什么意思呢?
KEYS[1]代表的是你加锁的那个key,比如说:
RLock lock = redisson.getLock(“myLock”);
这里你自己设置了加锁的那个锁key就是“myLock”。
ARGV[1]代表的就是锁key的默认生存时间,默认30秒。
ARGV[2]代表的是加锁的客户端的ID,类似于下面这样:8743c9c0-0795-4907-87fd-6c719a6b4586:1
第一段if判断语句,就是用“exists myLock”命令判断一下,如果你要加锁的那个锁key不存在的话,你就进行加锁。
2.1.3 如何加锁呢
很简单,用下面的命令:
hset myLock 8743c9c0-0795-4907-87fd-6c719a6b4586:1 1
通过这个命令设置一个hash数据结构,这行命令执行后,会出现一个类似下面的数据结构:
上述就代表“8743c9c0-0795-4907-87fd-6c719a6b4586:1”这个客户端对“myLock”这个锁key完成了加锁。
接着会执行“pexpire myLock 30000”命令,设置myLock这个锁key的生存时间是30秒。
好了,到此为止,ok,加锁完成了。
2.2 锁互斥机制 (客户端2来尝试加锁)
那么在这个时候,如果客户端2来尝试加锁,执行了同样的一段lua脚本,会咋样呢?
很简单,第一个if判断会执行“exists myLock”,发现myLock这个锁key已经存在了。
接着第二个if判断,判断一下,myLock锁key的hash数据结构中,是否包含客户端2的ID,但是明显不是的,因为那里包含的是客户端1的ID。
所以,客户端2会获取到pttl myLock返回的一个数字,这个数字代表了myLock这个锁key的剩余生存时间。比如还剩15000毫秒的生存时间。
此时客户端2会进入一个while循环,不停的尝试加锁。
2.3 watch dog自动延期机制
只要客户端1一旦加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端1还持有锁key,那么就会不断的延长锁key的生存时间。
2.4 可重入加锁机制
那如果客户端1都已经持有了这把锁了,结果可重入的加锁会怎么样呢?
第一个if判断肯定不成立,“exists myLock”会显示锁key已经存在了。
第二个if判断会成立,因为myLock的hash数据结构中包含的那个ID,就是客户端1的那个ID,也就是“8743c9c0-0795-4907-87fd-6c719a6b4586:1”
此时就会执行可重入加锁的逻辑,他会用incrby
,通过这个命令,对客户端1的加锁次数,累加1。
incrby myLock 8743c9c0-0795-4907-87fd-6c71a6b4586:1 1
此时myLock数据结构变为下面这样,那个myLock的hash数据结构中的那个客户端ID,就对应着加锁的次数
2.5 锁释放机制
如果执行lock.unlock(),就可以释放分布式锁,此时的业务逻辑也是非常简单的。
其实说白了,就是每次都对myLock数据结构中的那个加锁次数减1。
如果发现加锁次数是0了,说明这个客户端已经不再持有锁了,此时就会用:
“del myLock”命令,从redis里删除这个key。
然后呢,另外的客户端2就可以尝试完成加锁了。