Redisson分布式鎖:原理、使用

1. Redisson簡介

Redisson是一個基于Redis的Java客戶端庫,提供了豐富的分布式對象和服務(如分布式鎖、信號量、Map等)。其核心優勢在于??簡化分布式鎖的實現??,并解決了原生Redis分布式鎖的常見問題(如死鎖、誤刪鎖等)。


2. Redisson分布式鎖核心特性

2.1 鎖類型

  • ??可重入鎖(RLock)??:同一線程可重復獲取同一把鎖。
  • ??公平鎖(FairLock)??:按請求順序分配鎖,避免饑餓現象。
  • ??聯鎖(MultiLock)??:一次性鎖定多個資源。
  • ??紅鎖(RedLock)??:基于多Redis實例的高可用鎖。

可重入鎖(RLock)

可重入鎖是Redisson最基礎的鎖類型,允許同一線程多次獲取同一把鎖而不會造成死鎖。其核心原理是:

  • ??數據結構??:使用Redis的Hash結構存儲鎖信息,key為鎖名稱,field為線程標識(UUID+threadId),value為重入次數
  • ??重入機制??:當線程首次獲取鎖時,計數器設為1;同一線程再次獲取時計數器遞增,釋放時遞減,直到計數器歸零才真正釋放鎖
  • ??Lua腳本保證原子性??:加鎖和解鎖操作都通過Lua腳本實現,確保操作的原子性
// 獲取可重入鎖示例
RLock lock = redisson.getLock("myLock");
lock.lock();  // 第一次獲取鎖
try {lock.lock();  // 同一線程再次獲取鎖(重入)// 執行業務邏輯
} finally {lock.unlock();  // 釋放鎖(計數器減1)lock.unlock();  // 完全釋放鎖(計數器歸零)
}

公平鎖(FairLock)

公平鎖按照請求順序分配鎖資源,解決線程饑餓問題:

  • ??排隊機制??:使用Redis的List結構實現等待隊列(redisson_lock_queue:{lockName}),ZSet結構記錄超時時間(redisson_lock_timeout:{lockName})
  • ??公平獲取??:新線程獲取鎖時,必須檢查自己是否是隊列頭部,只有隊首線程才能獲取鎖
  • ??超時清理??:定期清理隊列中超時的線程請求,避免無效等待
// 公平鎖使用示例
RLock fairLock = redisson.getFairLock("fairLock");
fairLock.lock();
try {// 公平執行業務邏輯
} finally {fairLock.unlock();
}

聯鎖(MultiLock)

聯鎖用于同時鎖定多個資源:

  • ??原子性操作??:將多個RLock組合成一個鎖,所有鎖必須全部獲取成功才算成功
  • ??嚴格互斥??:默認要求所有鎖都必須成功獲取(failedLocksLimit=0)
  • ??適用場景??:如訂單系統中需要同時鎖定多個商品庫存的場景
// 聯鎖使用示例
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");RedissonMultiLock multiLock = new RedissonMultiLock(lock1, lock2, lock3);
multiLock.lock();
try {// 同時操作多個受保護資源
} finally {multiLock.unlock();
}

紅鎖(RedLock)

紅鎖是基于多Redis實例的高可用鎖:

  • ??多數派原則??:在N個獨立Redis節點上獲取鎖,至少成功(N/2 +1)個才算獲取成功
  • ??容錯機制??:即使部分節點故障,只要多數節點正常就能保證鎖可用
  • ??解決主從問題??:避免主從切換導致的鎖失效問題
// 紅鎖使用示例
RLock lock1 = redisson1.getLock("lock1");
RLock lock2 = redisson2.getLock("lock2");
RLock lock3 = redisson3.getLock("lock3");RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
redLock.lock();
try {// 執行高可用要求的業務邏輯
} finally {redLock.unlock();
}


2.2 關鍵機制

  • ??看門狗自動續期??:默認30秒檢查一次,若業務未完成則延長鎖過期時間。
  • ??鎖超時釋放??:避免死鎖,支持手動設置leaseTime
  • ??非阻塞嘗試??:通過tryLock(0, ...)實現立即返回。

3. 代碼示例

3.1 基礎鎖使用

// 1. 獲取RedissonClient實例(需提前配置Redis連接)
RedissonClient redisson = Redisson.create(config);// 2. 獲取鎖對象(鎖鍵為"myLock")
RLock lock = redisson.getLock("myLock");try {// 3. 嘗試獲取鎖,waitTime=0表示不重試,leaseTime=10秒表示鎖自動釋放時間boolean isLocked = lock.tryLock(0, 10, TimeUnit.SECONDS);if (isLocked) {// 4. 執行業務邏輯System.out.println("鎖獲取成功,執行業務...");} else {System.out.println("鎖獲取失敗,直接返回");}
} catch (InterruptedException e) {Thread.currentThread().interrupt();System.out.println("線程被中斷");
} finally {// 5. 釋放鎖(需判斷當前線程是否持有鎖)if (lock.isLocked() && lock.isHeldByCurrentThread()) {lock.unlock();}
}

3.2 注解式鎖(Spring集成)

@Service
public class InventoryService {private int stock = 100;// 使用@Lock注解聲明分布式鎖(鎖鍵為"decreaseStockLock")@Lock(name = "decreaseStockLock")public void decreaseStock() {if (stock > 0) {stock--;System.out.println("庫存扣減成功,剩余: " + stock);}}
}

4. 最佳實踐

  1. ??避免鎖過期??:若業務耗時不確定,建議不設置leaseTime(啟用看門狗)。
  2. ??防誤刪鎖??:在unlock()前校驗鎖持有者(isHeldByCurrentThread())。
  3. ??非阻塞場景??:使用tryLock(0, ...)快速失敗。

5.對比總結

特性可重入鎖公平鎖聯鎖紅鎖
核心特點同一線程可重復獲取按請求順序分配同時鎖定多個資源多節點高可用
數據結構Hash結構Hash+List+ZSet多個RLock組合多個獨立節點鎖
適用場景一般并發控制避免線程饑餓多資源原子操作高可用要求場景
性能影響中等(需維護隊列)高(需獲取所有鎖)高(多節點通信)

參加:騰訊元寶

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/75970.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/75970.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/75970.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java大廠面試題 -- JVM 優化進階之路:從原理到實戰的深度剖析(2)

最近佳作推薦: Java大廠面試題 – 深度揭秘 JVM 優化:六道面試題與行業巨頭實戰解析(1)(New) 開源架構與人工智能的融合:開啟技術新紀元(New) 開源架構的自動化測試策略優…

MySQL學習筆記(四)——DML和DQL

目錄 1. DML 1.1 添加數據 1.1.1 給指定字段添加數據 1.1.2 給全部字段添加數據 1.1.3 批量添加數據 1.2 修改數據 1.3 刪除數據 2. DQL 2.1 基本語法 2.2 基礎查詢 2.2.1 查詢多個字段 2.2.2 字段設置別名 2.2.3 去除重復記錄 2.3 條件查詢 2.4 聚合函數 2.5 …

DeepSeek-MLA

MLA 結構 需要緩存 KV 向量共用的壓縮隱特征K 向量多頭共享的帶位置編碼的向量 為什么帶有位置信息的 Q 向量來自于隱特征向量,而帶有位置的 K 向量來自于 H 向量且共享呢? 最好的方法肯定是從H向量直接計算并且不共享,但是會大大增加顯存使…

檢索增強技術RAG和向量數據庫技術的優勢和劣勢,應用范圍和價值

RAG 和向量數據庫在技術棧中處于不同層級,前者側重生成任務的準確性與動態性,后者專注檢索效率與擴展性。在實際應用中,二者常協同工作,但也可獨立服務于不同場景。企業需根據需求選擇:若需生成內容,RAG 是…

Python爬蟲教程013:使用CrawlSpider爬取讀書網數據并保存到mysql數據庫

文章目錄 3.8 CrawlSpider介紹3.9 CrawlSpider爬取讀書網案例3.9.1 創建項目3.9.2 定義要爬取的數據結構3.9.3 獲取數據3.9.4 保存數據到本地3.9.5 保存數據到mysql數據庫3.9.6 完整項目下載3.8 CrawlSpider介紹 CrawlSpider 是 Scrapy 框架中 最常用的高級爬蟲類之一,用于構…

Three.js 系列專題 5:加載外部模型

內容概述 Three.js 支持加載多種 3D 文件格式(如 GLTF、OBJ、FBX),這讓開發者可以直接使用專業建模軟件(如 Blender、Maya)創建的復雜模型。本專題將重點介紹 GLTF 格式的加載,并調整模型的位置和材質。 學習目標 理解常見 3D 文件格式及其特點。掌握使用 GLTFLoader 加…

P1006 [NOIP 2008 提高組] 傳紙條 題解

題目傳送門 前言 每次準備摸魚時都在這道題的界面。 今天有空做做,順便寫一波題解,畢竟估值蹭蹭往下跳。 雙倍經驗:P1004 [NOIP 2000 提高組] 方格取數,P1006 [NOIP 2008 提高組] 傳紙條。 題意簡述 現有一個 m m m 行 n …

LLM架構解析:長短期記憶網絡(LSTM)(第三部分)—— 從基礎原理到實踐應用的深度探索

本專欄深入探究從循環神經網絡(RNN)到Transformer等自然語言處理(NLP)模型的架構,以及基于這些模型構建的應用程序。 本系列文章內容: NLP自然語言處理基礎詞嵌入(Word Embeddings&#xff09…

ffmpeg提取字幕

使用ffmpeg -i test.mkv 獲取視頻文件的字幕流信息如下 Stream #0:4(chi): Subtitle: subrip (srt) (default) Metadata: title : chs Stream #0:5(chi): Subtitle: subrip (srt) Metadata: title : cht Stream #0:6(jpn)…

Python設計模式:構建模式

1. 什么是構建模式 構建模式(Builder Pattern)是一種創建型設計模式,它允許使用多個簡單的對象一步步構建一個復雜的對象。構建模式通過將構建過程與表示分離,使得同樣的構建過程可以創建不同的表示。換句話說,構建模…

使用 VIM 編輯器對文件進行編輯

一、VIM 的兩種狀態 VIM(vimsual)是 Linux/UNIX 系列 OS 中通用的全屏編輯器。vim 分為兩種狀態,即命令狀態和編輯狀態,在命令狀態下,所鍵入的字符系統均作命令來處理;而編輯狀態則是用來編輯文本資料&…

GaussDB回調機制深度實踐:從事件驅動到系統集成

GaussDB回調機制深度實踐:從事件驅動到系統集成 一、回調機制核心概念 回調類型矩陣 二、核心實現技術棧 觸發器回調開發 sql -- 創建審計觸發器回調 CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGININSERT INTO audit_log (operati…

AI小白:AI算法中常用的數學函數

文章目錄 一、激活函數1. Sigmoid2. ReLU(Rectified Linear Unit)3. Tanh(雙曲正切)4. Softmax示例代碼:激活函數的實現 二、損失函數1. 均方誤差(MSE)2. 交叉熵損失(Cross-Entropy&…

idea 打不開terminal

IDEA更新到2024.3后Terminal終端打不開的問題_idea terminal打不開-CSDN博客

Python代碼list列表的使用和常用方法及增刪改查

Python代碼list列表的使用和常用方法及增刪改查 提示:幫幫志會陸續更新非常多的IT技術知識,希望分享的內容對您有用。本章分享的是Python基礎語法。前后每一小節的內容是存在的有:學習and理解的關聯性,希望對您有用~ python語法-p…

Open CASCADE學習|讀取點集擬合樣條曲線(續)

問題 上一篇文章已經實現了樣條曲線擬合,但是仍存在問題,Tolerance過大擬合成直線了,Tolerance過大頭尾波浪形。 正確改進方案 1?? 核心參數優化 通過調整以下參數控制曲線平滑度: Standard_Integer DegMin 3; // 最低階…

Python基礎知識點(列表與字典)

列表list[] # list [12,34,56,78] # print(list) """ 1.list可以保存同一類型的數據 或 不同類型的數據 2.list是有序的,所以可以通過[下標]訪問元素 3.list保存重復的值 4.list是可變的,可以添加 刪除元素 """ …

在 Elasticsearch 中使用 Amazon Nova 模型

作者:來自 Elastic Andre Luiz 了解如何在 Elasticsearch 中使用 Amazon Nova 系列模型。 在本文中,我們將討論 Amazon 的 AI 模型家族——Amazon Nova,并學習如何將其與 Elasticsearch 結合使用。 關于 Amazon Nova Amazon Nova 是 Amazon …

MySQL8.0.40編譯安裝(Mysql8.0.40 Compilation and Installation)

MySQL8.0.40編譯安裝 近期MySQL發布了8.0.40版本,與之前的版本相比,部分依賴包發生了變化,因此重新編譯一版,也便于大家參考。 1. 下載源碼 選擇對應的版本、選擇源碼、操作系統 如果沒有登錄或者沒有MySQL官網賬號&#xff0…

python中pyside6多個py文件生成exe

網上見到的教程大多數都是pyinstaller安裝單個py文件,針對多個py文件的打包,鮮有人提及;有也是部分全而多的解釋,讓人目不暇接,本次記錄自己設置一個聲波捕捉界面的打包過程。 1.pycharm中調用pyinstaller打包 參考鏈接:https://blog.csdn.net/weixin_45793544/articl…