當前位置:編程學習大全網 - 源碼下載 - Redisson實現分布式鎖原理

Redisson實現分布式鎖原理

如圖所示啊,石杉大佬畫的redisson分布式鎖原理。

大概總結下,保證我們的key落到壹個集群裏,並且加鎖操作是基於lua腳本的原子性操作,對於鎖延遲由watch dog控制。

具體可以看 blogs.com/AnXinliang/p/10019389.html

如果妳對某個redis master實例,寫入了myLock這種鎖key的value,此時會異步復制給對應的master slave實例。但是這個過程中壹旦發生redis master宕機,主備切換,redis slave變為了redis master。

接著就會導致,客戶端2來嘗試加鎖的時候,在新的redis master上完成了加鎖,而客戶端1也以為自己成功加了鎖。

此時就會 導致多個客戶端對壹個分布式鎖完成了加鎖。

這時系統在業務語義上壹定會出現問題,導致各種臟數據的產生。

所以這個就是redis cluster,或者是redis master-slave架構的主從異步復制導致的redis分布式鎖的最大缺陷:在redis master實例宕機的時候,可能導致多個客戶端同時完成加鎖。

如果主動結構redis架構模式下,我們想保證完全壹致,必須重寫加鎖的邏輯了, 保證必須mater和slave同時加鎖成功,我們整個加鎖才是成功的 。

上面的2是對於單個主從結構我們可以這樣幹,如果假設我們有多個相對獨立的master,無slave呢?我們在其中壹個master上加了?,然後它掛了豈不是我們的數據會在剩下的結點會重新加鎖成功?

redis引入了 紅鎖 的概念:用Redis中的多個master實例,來獲取鎖,只有 大多數 實例獲取到了鎖,才算是獲取成功

具體的紅鎖算法分為以下五步:

以上步驟來自redis 分布式鎖的解釋,如下

”相同的key和隨機值(隨機值用於唯壹關系客戶端和key)在N個節點上請求鎖“

這裏的隨機數是什麽?

這對於 避免刪除由另壹個客戶端創建的鎖 很重要。例如,客戶端可能會獲取鎖,執行某些操作時被阻塞的時間超過鎖的有效時間(密鑰將過期的時間),然後移除已被其他客戶端獲取的鎖。使用 just DEL 是不安全的,因為客戶端可能會刪除另壹個客戶端的鎖。使用上面的腳本,每個鎖都用壹個隨機字符串“簽名”,所以只有當它仍然是客戶端試圖移除它時設置的鎖才會被移除。

這個隨機字符串應該是什麽?我們假設它是 20 個字節 /dev/urandom ,但您可以找到更便宜的方法使其對您的任務足夠獨特。例如,壹個安全的選擇是用 RC4 播種 /dev/urandom ,並從中生成壹個偽隨機流。壹個更簡單的解決方案是使用具有微秒精度的 UNIX 時間戳,將 時間戳與客戶端 ID 連接起來。它並不安全,但對於大多數環境來說可能就足夠了。

假設壹***有5個Redis節點:A, B, C, D, E。設想發生了如下的事件序列:

為了應對這壹問題,提出了 延遲重啟 (delayed restarts)的概念。

就是,壹個節點崩潰後,先不立即重啟它,而是等待壹段時間再重啟,這段時間應該大於鎖的有效時間(lock validity time)。

這樣的話,這個節點在重啟前所參與的鎖都會過期,它在重啟後就不會對現有的鎖造成影響。

客戶端1在獲得鎖之後發生了很長時間的GC pause,在此期間,它獲得的鎖過期了,而客戶端2獲得了鎖。

當客戶端1從GC pause中恢復過來的時候,它不知道自己持有的鎖已經過期了,它依然向***享資源( 比如 壹個存儲服務)發起了寫數據請求,

而這時鎖實際上被客戶端2持有,因此兩個客戶端的寫請求就有可能沖突(鎖的互斥作用失效了)。

如何解決這個問題呢?引入了 fencing token 的概念:

首先:RedLock根據隨機字符串來作為單次鎖服務的token,這就意味著對於資源而言,無法根據鎖token來區分client持有的鎖所獲取的先後順序。

fencing token可以理解成采用全局遞增的序列替代隨機字符串,即 有序token ,作為鎖token來使用

流程:

假設有5個Redis節點A, B, C, D, E。

這個問題用Redis實現分布式鎖暫時無解。而生產環境這種情況是存在的。

時鐘跳躍是可以避免的,取決於基礎設施和運維; 時鐘跳躍是可以避免的,取決於基礎設施和運維;

redis是保持的AP而非CP,如果要追求強壹致性可以使用zookeeper分布式鎖,但是zookeeper也不是完全沒問題,在出現網絡顏值,客戶端與服務端失聯情況的時候也依然可能會出現分布式的問題。

  • 上一篇:想建壹個購物商城網站, 用什麽空間系統好?Windows還是linux
  • 下一篇:線程池執行服務
  • copyright 2024編程學習大全網