深入解析Redisson分布式鎖看門狗機制
一、Redisson分布式鎖概述 ??
?? 1.1 分布式鎖的意義
在分布式系統(tǒng)中,多個節(jié)點可能同時訪問共享資源,導致數(shù)據(jù)不一致或競態(tài)條件。分布式鎖通過協(xié)調不同節(jié)點對共享資源的訪問,確保數(shù)據(jù)的一致性和并發(fā)訪問的安全性。
?? 1.2 Redisson分布式鎖的優(yōu)勢
- 基于Redis實現(xiàn):Redis作為高性能的內存數(shù)據(jù)庫,提供了快速、穩(wěn)定的存儲服務,為Redisson分布式鎖提供了堅實的基礎。
- 豐富的API:Redisson提供了豐富的Java API,使得分布式鎖的使用更加簡單、直觀。
- 自動續(xù)期機制:Redisson的分布式鎖支持自動續(xù)期,避免了因業(yè)務處理時間過長導致的鎖過期問題。
- 可重入鎖:Redisson的分布式鎖支持可重入特性,即同一個線程可以多次獲取同一把鎖。
二、Redisson分布式鎖的原理 ??
?? 2.1 鎖的實現(xiàn)方式
Redisson分布式鎖主要基于Redis的SETNX(Set if Not Exists)命令和DEL(Delete)命令實現(xiàn)。SETNX命令嘗試設置一個值,如果該鍵不存在,則設置成功并返回1;否則返回0。DEL命令則用于刪除一個鍵。
?? 2.2 看門狗機制
- Redisson通過看門狗(Watch Dog)機制來實現(xiàn)鎖的自動續(xù)期。當一個沒有
leaseTime線程獲取鎖后,Redisson會立即啟動一個后臺的定時任務(看門狗)來定期檢查鎖的狀態(tài)。 - 看門狗的時間間隔通常是鎖默認過期時間(如
30秒)的三分之一(即10秒)。 - 如果線程在鎖的默認過期時間內完成了操作并釋放了鎖,看門狗會檢測到鎖的釋放并取消該定時任務,避免不必要的資源消耗。
- 看門狗機制只會針對沒有設置
leaseTime的鎖;設置了leaseTime的鎖不會有看門狗機制,會根據(jù)設置的過期時間自然過期。 - 看門狗是由redisson維護的,當java服務進程中斷時,看門狗也會中斷,redis鎖將自然過期。
?? 2.3 鎖的自動續(xù)期機制
- 每當觸發(fā)看門狗機制時,它會嘗試自動續(xù)期,續(xù)期的時間長度通常是鎖的默認過期時間(如再次設置為30秒),但也可以根據(jù)具體需求進行調整。
?? 2.4 鎖的釋放
當一個線程完成臨界區(qū)的操作后,應當手動釋放鎖。在Redisson中,這通常通過調用unlock()方法來完成。如果線程沒有手動釋放鎖,而是異常結束或被其他方式中斷,Redis的鍵空間通知功能可以確保鎖在一段時間后自動釋放。
三、Redisson 看門狗機制 ??
?? 3.1 參數(shù)說明
waitTime: 表示在嘗試獲取鎖之前,線程會等待多長時間(前提:鎖被占用)。當waitTime設置為大于0的值時,線程在嘗試獲取鎖時會在指定的時間內等待。如果在這段時間內鎖沒有被獲取到,tryLock方法將返回false。leaseTime: 表示鎖的持有時間,即鎖在自動釋放之前可以保持多久。unit: 時間單位,用于指定waitTime和leaseTime的時間單位。
?? 3.2 舉例幾個常見的方法
RLock lock = redissonClient.getLock("lockKey001");
// 沒設置leaseTime,有看門狗機制
lock.tryLock();
// 實際調用的RedissonLock的tryLock(long waitTime, TimeUnit unit)
// 沒設置leaseTime,有看門狗機制
lock.tryLock(3, TimeUnit.SECONDS);
// 實際調用的RedissonLock的lock(long leaseTime, TimeUnit unit)方法
// 設置了leaseTime,沒有看門狗機制
lock.lock(10, TimeUnit.SECONDS);
// 設置了leaseTime=10s,沒有看門狗機制
lock.tryLock(3,10, TimeUnit.SECONDS);
?? 3.3 tryLock()
tryLock() 方法默認會有看門狗機制,因為沒有設置過期時間,默認是30s過期,但是看門狗每10s續(xù)期一次,每次續(xù)期都重新設置過期時間為30s。如果沒有釋放鎖,理論上會無限續(xù)期。
?? 3.4 tryLock(long waitTime, TimeUnit unit)
// 源碼
public boolean tryLock(long waitTime, TimeUnit unit) throws InterruptedException {
return this.tryLock(waitTime, -1L, unit);
}
因為這個方法沒有設置 leaseTime,因此默認也是有看門狗機制的。默認是30s過期,但是看門狗每10s續(xù)期一次,每次續(xù)期都重新設置過期時間為30s。如果沒有釋放鎖,理論上會無限續(xù)期。
?? 3.5 lock(long leaseTime, TimeUnit unit)
設置了 leaseTime 不會有看門狗機制
// 源碼
public void lock(long leaseTime, TimeUnit unit) {
try {
this.lockInterruptibly(leaseTime, unit);
} catch (InterruptedException var5) {
Thread.currentThread().interrupt();
}
}
?? 3.6 tryLock(long waitTime, long leaseTime, TimeUnit unit)
設置了 leaseTime 不會有看門狗機制
// 源碼
public boolean tryLock(long waitTime, long leaseTime, TimeUnit unit) throws InterruptedException {
long time = unit.toMillis(waitTime);
long current = System.currentTimeMillis();
...........
}
四、其他 ??
?? 4.1 看門狗生命周期
當一個沒有設置leaseTime 的鎖一創(chuàng)建 Redisson 就會生成一個對應的看門狗,如果執(zhí)行了unlock()則看門狗會一起銷毀。不然會直到java進程終止(重啟、銷毀)才會消失。
?? 4.2 看門狗是Redisson 生成的嗎
是的,看門狗機制是Redisson 后臺啟的一個定時任務,不是Redis自帶的。
到此這篇關于深入解析Redisson分布式鎖看門狗機制的文章就介紹到這了,更多相關Redisson分布式鎖看門狗內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java Socket實現(xiàn)Redis客戶端的詳細說明
socket編程是一門技術,它主要是在網絡通信中經常用到.這篇文章主要介紹了如何用Java Socket實現(xiàn)一個簡單的Redis客戶端,需要的朋友可以參考下2021-05-05
Redis數(shù)據(jù)導出之多文件輸出與編碼問題的完整解決方案
Python作為數(shù)據(jù)處理的重要工具,結合Redis模塊可以輕松實現(xiàn)這一功能,然而,在實際操作過程中會出現(xiàn)多文件輸出混亂和字符編碼錯誤,下面我們來看看具體的解決方法吧2025-08-08
Redis?使用?List?實現(xiàn)消息隊列的優(yōu)缺點
這篇文章主要介紹了Redis?使用?List?實現(xiàn)消息隊列有哪些利弊,小編結合消息隊列的特點一步步帶大家分析使用?Redis?的?List?作為消息隊列的實現(xiàn)原理,并分享如何把?SpringBoot?與?Redission?整合運用到項目中,需要的朋友可以參考下2022-01-01
redis?for?windows?6.2.6安裝包最新步驟詳解
這篇文章主要介紹了redis?for?windows?6.2.6安裝包全網首發(fā),使用Windows計劃任務自動運行redis服務,文章給大家講解的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
詳解Redis中的簡單動態(tài)字符串和C字符串的區(qū)別
簡單動態(tài)字符串(SDS)和?C?字符串在實現(xiàn)和特性上存在一些區(qū)別,這些區(qū)別使得?SDS?更適合作為?Redis?中字符串對象的內部表示,本文給大家介紹一下Redis中的簡單動態(tài)字符串和C字符串的區(qū)別,需要的朋友可以參考下2023-12-12

