十三、redis分布式锁:缓存续命

一、什么是缓存续命

Redis 分布式锁过期了,但是业务逻辑还没处理完怎么办?

守护线程续命,额外起一个线程,定期检查线程是否还持有锁,如果有则延长过期时间。Redisson 里面就实现了这个方案,使用 “看门狗” 定期检查(每1/3的锁时间检查1次),如果线程还持有锁,则刷新过期时间。

在获取锁成功后,给锁加一个 watchdog,watchdog 会起一个定时任务,在锁没有被释放且快要过期的时候会续期。

 

注意:

  • lock() 方法加锁成功 默认过期时间 30 秒, 并且支持 "看门狗" 续时功能。
  • 如果设置leaseTime,则不会开启“看门狗”。

 

二、源码分析

1、源码1

通过redisson新建出来的锁key,默认是30秒。

 

 

  2、源码2

 

3、源码3

 

 这里面初始化了一个定时器,dely 的时间是 internalLockLeaseTime/3。在 Redisson 中,internalLockLeaseTime 是 30s,也就是每隔 10s 续期一次,每次 30s。

watch dog自动延期机制

客户端A加锁成功,就会启动一个watch dog看门狗,他是一个后台线程,会每隔10秒检查一下,如果客户端A还持有锁key,那么就会不断的延长锁key的生存时间,默认每次续命又从30秒新开始。

4、源码4

底层的lua脚本

KEYS[1]代表的是你加锁的那个key RLock redissonLock = redisson.getLock("lockzzyy");这里你自己设置了加锁的那个锁key
ARGV[2]代表的是加锁的客户端的ID
ARGV[1]就是锁key的默认生存时间 默认30秒
如何加锁 你要加锁的那个锁key不存在的话,你就进行加锁
hincrby 7bcf6a9f-e7f7-49b0-9727-141df3b88038:117 1
接着会执行 pexpire lockzzyy 30000

 

流程解释

(1)通过exists判断,如果锁不存在,则设置值和过期时间,加锁成功。

(2)通过hexists判断,如果锁已存在,并且锁的是当前线程,则证明是重入锁,加锁成功。

(3)如果锁已存在,但锁的不是当前线程,则证明有其他线程持有锁。返回当前锁的过期时间(代表了lockzzyy这个锁key的剩余生存时间),加锁失败。

 

加锁成功后,在redis的内存数据中,就有一条hash结构的数据。

Key为锁的名称;field为随机字符串+线程ID;值为1。见下

 

如果同一线程多次调用lock方法,值递增1。——可重入锁

 

 

 5、解锁

 

posted @   幻月hah  阅读(2167)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· DeepSeek “源神”启动!「GitHub 热点速览」
· 上周热点回顾(2.17-2.23)
点击右上角即可分享
微信分享提示