一、什么是緩存續命
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、解鎖