首頁 > 資料庫 > Redis > Redis中分散式鎖Redlock的範例分析

Redis中分散式鎖Redlock的範例分析

王林
發布: 2023-05-28 20:34:57
轉載
1176 人瀏覽過

Redlock實作庫

  • Java Redisson Star 9458

  • C# RedLock.net Star 259

  • Go redsync.go Star 249

#雖然後面的演算法是一樣的,不過這個按讚數確實服。

單點Redis鎖定

先簡單回顧一下單點的Redis鎖定是怎麼實現的。

取得鎖定

SET resource_name my_random_value NX PX 30000
登入後複製

客戶端A使用Redis設定一個鍵值對,並指定逾時時間以避免死鎖。當其他用戶端存取時,它們會先檢查該鍵是否已存在,且其值是否為「my_random_value」。如果已存在就等待,否則就取得成功,執行業務代碼。所有客戶端共用且已知的物件包括resource_name和my_random_value。

釋放鎖定

if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1])else return 0end
登入後複製

對比key取得到的對應的value是否相等,如果相等,就刪除(釋放),否則就回傳失敗。

單點Redis鎖定的缺陷

只有一個Redis實例時,發生故障會導致所有依賴它的服務都崩潰,這個缺陷異常明顯。顯然不太適合大型的應用。

簡單的Redis主從架構碰到的問題

為了避免單點故障,我們給Redis一個Master/Slave的主從架構,一個Master,一台Slave。下面就會碰到這麼一個問題。下面是使用場景。

  1. 客戶端A在Master上取得到一個鎖。

  2. Master把這個資料同步到Slave的時候掛了(因為Master和Slave之間同步是異步的)。

  3. Slave變成了Master。

  4. 客戶端B透過相同的key,和value取得到鎖定。分散式鎖定失效

Redlock演算法

#假設我們有N(假設5)個Redis  master實例,所有節點相互獨立,且業務系統也是單純的調用,並沒有其他的類似訊息重發之類的輔助系統。下面來模擬演算法:

     1.客戶端取得伺服器目前的的時間t0,毫秒數。

在5個實例中使用相同的key和value取得鎖定。在取得業務鎖時,用戶端會設定一個持續時間遠小於業務鎖所需的逾時時間。舉個例子,假設鎖需要10秒鐘,可以將超時時間設定在5-50毫秒之間。重寫後的句子: 為了避免客戶端在嘗試取得鎖時出現Redis已經故障的情況,需要採取措施。超時了之後就直接跳到下一個節點。

      3.客戶端透過目前時間(t1)減去t0,計算取得鎖定所消耗的時間t2(=t1-t0)。只有t2小於鎖的業務有效時間(也就是第二步的10秒),並且,客戶端在至少3(5/2 1)台上獲取到鎖我們才認為鎖獲取成功。

      4.如果鎖定已經獲取,那麼鎖定的業務有效時間為10s-t2。

      5.如果客戶端沒有取得到鎖,可能是沒有在大於等於N/2 1個實例上取得鎖,也可能是有效時間(10s-t2)為負數,我們就嘗試去釋放鎖,即使是並沒有在那個節點上取得到。

鎖定的釋放

釋放比較簡單,直接刪除所有實例上對應的key就好。

以上是Redis中分散式鎖Redlock的範例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:yisu.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板