Redission Distributed Lock 原理分析

Mondo 科技 更新 2024-02-20

一、引言

我們先來談談分布式鎖,為什麼要有分布式鎖呢? 實現 jdk 提供的 synchronized、lock 等鎖不是很好嗎? 這是因為在單程序的情況下,多個執行緒訪問同乙個資源,可以使用 synchronized 和 lock 來實現; 在多個程序的情況下,即在分布式的情況下,需要使用分布式鎖來實現對同一資源的併發請求。 Redisson 元件可以實現 Redis 的分布式鎖,Redisson 也是官方推薦的 Redis 分布式鎖實現方案,封裝後讓使用者實現分布式鎖更加方便簡潔。

2. 分布式鎖的特點

相互排斥任何時候,只有乙個客戶端可以獲取乙個鎖,並且沒有兩個客戶端可以同時獲取乙個鎖。 身份鎖只能由持有鎖的客戶端刪除,不能由其他客戶端刪除。 重入持有鎖的客戶端可以繼續鎖定鎖並續訂鎖。 容錯當乙個鎖失敗(超過其生命週期結束時)時,鎖會自動釋放(金鑰無效),其他客戶端可以繼續獲取該鎖以防止死鎖。 3. Redisson分布式鎖原理

在下文中,我們從五個方面分析了雷迪森分布式鎖的原理:鎖機制、鎖互斥機制、鎖更新機制、可重入鎖機制和鎖釋放機制。

3.0 整體分析

注意:Redisson 版本 324.4-snapshot

**微信***老周聊天架構】*公共類RedissonLockTest終於 }
初始化 redissonlock

** 鎖定方式 * param leasetime 鎖定過期時間(-1:使用預設值 30 秒) *param 單位時間單位 * param 可以中斷 * 丟擲 interruptedException * private void lock(long leasetime, timeunit unit, boolean interruptibly) 丟擲 interruptedexception 訂閱分布式鎖,解鎖時通知。  completablefuture future = subscribe(threadid); pubsub.timeout(future); redissonlockentry entry;如果 (interruptablely) else try waiting for message 如果鎖過期時間大於零,則執行具有過期時間的阻塞取取。  if (ttl >= 0) catch (interruptedexception e) entry.getlatch().tryacquire(ttl, timeunit.milliseconds); else else }finally }

當鎖定超時時間為 -1 且成功獲取鎖定時,將啟動看門狗定時任務,自動續訂鎖定

每次續鎖時,都需要判斷鎖是否已經鬆開,如果續鎖成功,您將再次安排自己繼續續鎖操作。

為了保證原子性,見31 鎖定機構。

3.1 鎖定機構。

鎖定機制的核心就是這一部分,其中 lua 指令碼被包裹在 redisoon 中,最後通過 netty 傳輸。

rfuture trylockinnerasync(long waittime, long leasetime, timeunit unit, long threadid, redisstrictcommand command)
當你去乙個波時,斷點很清楚:

keys[1]) 鍵

ar**[1]:金鑰的存活時間,預設為 30 秒。

ar**[2]:鎖定的客戶端 ID (uuidrandomuuid())threadid)

上一段中帶鎖的 lua 指令碼的作用是:第乙個 if 判斷語句是使用 exists mylock 命令來判斷,如果要鎖定的鎖鍵不存在(第乙個鎖)或者鍵的字段存在(reentrant lock),則將其鎖定。 如何鎖定它? 使用 hincrby 命令設定雜湊結構,類似於在 Redis 中執行的操作,如下所示:

整個 lua 指令碼鎖定過程如下圖所示:

如您所見,最新版本的邏輯比以前的版本更簡單、更清晰。

3.2 鎖定互斥機制

此時,如果客戶端 2 嘗試鎖定它,該怎麼辦? 首先,第乙個 if 判斷將執行存在 mylock,並且會發現鎖鍵 mylock 已經存在。 那麼第二個if判斷就是判斷mylock鎖鍵的雜湊資料結構是否包含客戶端2的ID,這顯然不是,因為它包含了客戶端1的ID。 因此,客戶端 2 執行:

return redis.call('pttl', keys[1]);
返回的數字,表示 mylock 金鑰的剩餘生存時間。

鎖互斥機制實際上是主要過程3.0 整體分析你可以看到這個組織redisson.redissonlock#lock(long, j**a.util.concurrent.timeunit,布林值)。

3.3 鎖倉續期機制

客戶端 1 新增的鎖鍵預設生存時間為 30 秒,如果超過 30 秒,客戶端 1 想要保留鎖應該怎麼做?

Redisson 提供了一種續訂機制,該機制在客戶端 1 被鎖定後立即啟動看門狗。

3.4 再入鎖定機構

看門狗機制實際上是乙個後台排程任務執行緒,在成功獲取鎖後,持有鎖的執行緒會被放入乙個redissonbaselock中過期續費對映,然後每 10 秒檢查一次(internallockleasetime 3),客戶端 1 是否仍然持有鎖鍵(判斷客戶端是否還持有金鑰,其實就是遍歷過期續費對映中的執行緒 ID,然後根據執行緒 ID 在 redis 中檢查,如果存在, 鑰匙的時間會延長),然後鎖會不斷延長鑰匙的壽命。

注意:

如果服務宕機,看門狗機制執行緒會消失,金鑰的過期時間不會延長,30s後會自動過期,其他執行緒可以拿到鎖。

如果呼叫具有過期時間的鎖定方法,則監視程式任務不會啟動以自動續訂。

3.5 鎖定釋放機制

確定 keys[1] 中是否存在 ar**[3]。"if (redis.call('hexists', keys[1], ar**[3]) == 0) then " + "return nil;" +"end; "+ 替換 ar**[3] val - 1 中的鍵 [1]"local counter = redis.call('hincrby', keys[1], ar**[3], 1); "+ 如果返回值大於 0,則證明它是可重入鎖"if (counter > 0) then "+ 重置過期時間"redis.call('pexpire', keys[1], ar**[2]);" + "return 0; " +"else "+ 刪除鍵[1]。"redis.call('del', keys[1]);"+ 等待執行緒或程序資源可用的通知阻止"redis.call('publish', keys[2], ar**[1]);" + "return 1; " +"end; " +"return nil;"
keys[1]: mylock

keys[2]: redisson_lock_channel:

ar**[1]: 0

ar**[2]:30000(過期時間)。

ar**[3]: 66a84a47-3960-4f3e-8ed7-ea2c1061e4cf:1 (雜湊中的鎖定字段)。

同樣,鎖釋放斷點也會出現波浪:

鎖釋放機制摘要:

移除鎖(注意此處的可重入鎖)會廣播一條訊息以釋放鎖,通知阻塞等待過程(到名為 Redisson Lock Channel 的通道:發布解鎖訊息)以取消看門狗機制,即 RedissonLock刪除到期續費對映中的執行緒 ID,並取消 Netty 的定時任務執行緒。

四、主從Redis架構中分布式鎖的問題

執行緒 A 向主 Redis 請求分布式鎖,並成功獲取該鎖。 當主 Redis 準備同步來自主 Redis 的鎖資訊時,主 Redis 突然關閉,鎖丟失。 觸發從 Redis 到新主 Redis 的公升級; 執行緒 B 從後繼 Redis 的 Slave Redis 申請分布式鎖,可以成功獲取該鎖。 這樣一來,兩個客戶端同時獲取相同的分布式鎖,沒有獨佔使用功能; 為了解決這個問題,Redis 引入了紅鎖的概念。

您需要準備多個Redis例項,這些例項彼此完全獨立,並且這些節點之間沒有主從關係。 當客戶端申請分布式鎖時,需要向所有Redis例項傳送乙個應用,只有當超過一半的Redis例項報告鎖已成功獲取時,才能認為該鎖已獲得。 與大多數保證一致性的演算法類似,這是多數原則。

public static void main(string args) finally }
當然,RedLock演算法是毋庸置疑的,兩位神仙在幾年前就吵過架,有興趣的話可以去Redis官網檢視一下Martin Kleppmann和Redis作者Antirez的爭論。

好吧,我想收集它,如果繼續談論它,我感覺我無法繞過分布式經典問題上限。

5. 分布式鎖選擇

如果想要強一致性,可以選擇 zk 的分布式鎖,但是 zk 的效能會在一定程度上下降,如果專案不使用 zk,那就選擇 redis 的分布式鎖,比較你的效能為那個非常小的概率,引入乙個元件是不划算的,如果不能容忍 redis 的紅鎖缺陷, 然後你可以自己在業務中保證。

以下是幾種常見的分布式鎖選擇的比較:

如果您喜歡這篇文章,請點選右上角與您的朋友分享文章。

想要了解學習的技術要點,請留言若飛安排分享。

由於***推送規則變更,請點選“觀看”並新增“星標”,即可第一時間獲得精彩技術分享

·end·

相關閱讀:
了解微服務架構路線的圖表:基於Spring Cloud的微服務架構分析:微服務等於Spring Cloud? 了解微服務架構和框架如何構建基於 DDD 的域驅動型微服務? 對於乙個小團隊來說,引入SpringCloud微服務真的很合適嗎? DDD興起的原因及其與微服務的關係呼叫微服務的最佳方式微服務架構設計總結基於Kubernetes的微服務專案設計與實現微服務架構-設計總結為什麼微服務必須有閘道器? 主流微服務全鏈路監控系統之戰,詳細講解了微服務架構的實現原理,微服務的介紹和技術棧,設計了微服務場景下的資料一致性解決方案,設計了容錯微服務架構
作者: riemannchow

*:老周談建築。

版權宣告:內容**網路,僅供學習和研究使用,版權歸原作者所有。 如有侵權,請告知我們,我們將立即刪除並道歉。 謝謝!

相關問題答案

    Apache SINGA 是分布式深度學習 習 的引擎

    Apache Singa是乙個功能強大的開源深度學習習框架,專為分布式計算環境而設計。在本文中,我們將了解Apache Singa的優缺點,它與類似框架的比較,以及如何選擇這個深入學習的習引擎。對分布式計算的強大支援 Apache Singa專注於分布式深度學習習計算,使其成為處理大規模資料和模型的...

    分布式矩陣系統

    分布式矩陣系統是基於分布式計算原理的矩陣計算框架。這樣就把大規模的矩陣資料分成幾個小塊,把這些小塊分發到不同的計算節點進行平行計算,從而實現快速矩陣計算和分布式計算。與普通矩陣系統相比,分布式矩陣系統在以下方面有所不同 處理大規模資料 分布式矩陣系統針對處理大規模矩陣資料進行了優化。為了平行計算大規...

    什麼是分布式VPN?DataSky 是如何實現分布式 VPN 的?

    什麼是分布式VPN?信達天航使用無線AP在分支節點和總部伺服器之間形成內網。DataSky分布式VPN組網解決方案解決了分支節點連線總部的網路需求,具有以下優勢 簡單易用 分布式VPN是一種簡單易部署的虛擬專用網路解決方案。客戶可以使用 DSE 無線 AP 裝置輕鬆地在分支節點和總部伺服器之間建立安...

    TDengine是一款高效能的分布式物聯網工業大資料平台

    TDengine投融資專案 本專案由TDEngine提交,參與評選 資料猿年度金猿策劃活動 大資料行業年度最具價值投資榜評選 北京陶思資料技術有限公司成立於年月,瞄準日益增長的物聯網資料市場,專注於時序空間中大資料的儲存 查詢 分析和計算,在不依賴任何開源或第三方軟體的情況下,開發了具有自主智財權和...

    Seata打造業界首款分布式交易產品

    作者 Ji Min,阿里雲分布式交易產品負責人,Seata開源專案創始人。微服務開發痛點 年,我們以 Dubbo 生態 Meetup 為基礎,收集了 多篇關於 開發者最關心的微服務架構核心問題是什麼?最後,分布式事務問題佔調查比例最大,約佔 在Seata出現之前,分布式事務的態度是迴避它們,它們大多...