目录
Redisson工作原理图
Redisson工作原理
1.lua脚本
现在某个客户端要加锁,且该客户端面对是上图中的Redis Cluster集群,他会首先根据hash节点选择一台机器,紧接着会发送一段lua脚本(胶水语言)到redis上。
为什么用lua脚本,因为lua可以保证一大坨代码执行的原子性。
2.加锁
上图的代码是什么意思呢?KEYS【1】代表加锁的key名称,比如
ARGV【1】代表key的默认生产时间,默认30s
ARGV【2】代表加锁的客户端ID,类似于下面的字符串
上图中的第一个if是用来判断要加锁的key是否不存在,如果不存在,就进行加锁
如果加锁呢?使用hset进行key value加锁
上面的命令会出现下面的数据结构
接着会执行pexpire myLock 30000命令,设置myLock锁key的生存时间是30s,到此加锁完成
3.锁互斥机制
如果客户端1拿到了锁,客户端2尝试加锁,执行了同样的一段lua脚本,会发生什么?第一个if判断会执行exists myLock,发现myLock这个锁key已经存在了,会走到第二个if判断,myLock锁key的hash数据结构中,是否包含客户端2的ID,答案当然是不包含,所有客户端2会获得pttl myLock返回的一个数字,这个数字代表myLock这个锁key的剩余生产时间。比如还剩15000毫秒的生存时间。
此时客户端2会进入一个while循环,不停尝试加锁
4.watch dog自动延期机制
客户端1加锁的key默认生存时间是30s,一旦客户端1加锁成功,就会启动一个watch dog,它是一个后台线程会每隔10s检查一下,如果客户端1还持有锁key,那么就会不断延长锁key的生存时间。
5.可重入锁机制
如果客户端1已经加锁了,可重入再加锁会怎样?
首先第一个if判断不成立,第二个if判断会成了,此时它会调用+1的逻辑
myLock的数据结构变成下面的样子,最后的2代表加锁的次数
6.释放锁机制
如果执行lock.unlock()就可以释放分布式锁。它所做的操作也很简单,就是在上图的基础上-1,如果发现加锁次数是0了就说明这个客户端已经不再持有锁了,此时用del myLock命令删除key即可,然后客户端2就可以尝试完成加锁了。
代码实现步骤
引入Jar包
注入Bean容器
使用