暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

redisson分布式读写锁-读锁watchDog原理

程序猿西蒙 2021-12-05
1649

redisson分布式锁文章回顾

redisson分布式可重入锁加锁原理

redisson分布式锁-watch dog原理

分布式可重入锁原理-锁互斥原理

分布式可重入锁原理-释放锁原理

Redisson分布式可重入锁-加锁超时机制

redisson分布式公平锁-加锁原理

redisson分布式公平锁-队列重排

redisson分布式公平锁-释放锁原理

redisson分布式锁-Multi锁原理

redisson-RedLock原理


NO.1


回顾


前面的章节,我们分析了redisson读锁的加锁原理,读锁可以允许多个客户端同时加锁,读锁的原理比较简单,在redis中添加一个mode属性来标识锁的模式,然后设置持有锁的客户端以及当前客户端的加锁次数,并且设置一个给客户端设置一个超时时间,一个客户端重复获取锁后,redis中的数据如下所示:
{
"anyLock": {
"mode": "read",
    "uuid01:threadId01"3
}
}
{anyLock}:uuid01:threadId01:rwlock_timeout:1 1
{anyLock}:uuid01:threadId01:rwlock_timeout:2 1
{anyLock}:uuid01:threadId01:rwlock_timeout:3 1
复制

NO.2


问题

加锁成功之后,如果业务执行时间超过了锁的时间,那么怎么保持锁不过期呢?
在Redisson可重入锁的文章中,我们讲过watchDog机制,我们知道可以进行锁的续约,保证锁能不过期,那么读锁这里也是通过watchDog来进行锁续约的

NO.3


读锁的watchDog原理

我们知道在加锁成功了之后,会开启一个watchDog,来定时的进行锁的续约,核心方法是在renewExpirationAsync()方法中,在里面定义了如下续约的lua脚本

local counter = redis.call('hget', KEYS[1], ARGV[2]);  
if (counter ~= false) then
    redis.call('pexpire', KEYS[1], ARGV[1]);      
if (redis.call('hlen', KEYS[1]) > 1) then
local keys = redis.call('hkeys', KEYS[1]);
for n, key in ipairs(keys) do
counter = tonumber(redis.call('hget', KEYS[1], key));
if type(counter) == 'number' then
for i=counter, 1, -1 do
redis.call('pexpire', KEYS[2] .. ':' .. key .. ':rwlock_timeout:' .. i, ARGV[1]);
end;
end;
end;
end;
   return 1;  
end;
return 0;
复制

说明:

  1. keys[1] : anyLock 就是我们声明的锁名字

  2. argv[1] : 30000ms

  3. argv[2] : 客户端唯一标识 => uuid01:threadId01


watchDog续约的核心逻辑:

  1. 执行hget anylock uuid01:threadId01的value值,获取加锁的次数,判断是否持有锁,如果没有直接返回

  2. 如果持有锁,执行pexpire anyLock 30000重置过期时间

  3. 判断锁的属性个数是否大于1,我们知道读锁加锁成功之后,会有mode和客户端标识属性

  4. 获取锁的所有属性值,循环遍历所有的属性值,找到非mode以外的属性

  5. 获取当前客户端加锁的次数,我们知道一个客户端重复的加锁,在redis中会记录下面类似的数据,来记录客户端锁的过期时间

    {anyLock}:uuid01:threadId01:rwlock_timeout:1 1
    {anyLock}:uuid01:threadId01:rwlock_timeout:2 1
    {anyLock}:uuid01:threadId01:rwlock_timeout:3 1
    复制
  6. 所以watchDog在进行续约的时候,需要重置上面数据的超时时间,

  7. 上面lua脚本最内层的for循环就是重置上面数据的超时时间



NO.3


总结


watchDog的原理其实也很简单,对于某一个客户端,如果加锁成功之后,会开启一个WatchDog每隔10s进行一次锁的续约,他会先重置锁key的过期时间为30s,然后判断这个客户端重复加锁几次,然后给客户端的超时标志也进行续约,重置标志的超时时间为30s





点个在看你最好看



文章转载自程序猿西蒙,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论