Redlock分布式鎖

2021-09-29 07:25:08 字數 1754 閱讀 3111

這篇文章主要是對 redis 官方**刊登的 distributed locks with redis 部分內容的總結和翻譯。

安全特性:互斥訪問,即永遠只有乙個 client 能拿到鎖

避免死鎖:最終 client 都可能拿到鎖,不會出現死鎖的情況,即使原本鎖住某資源的 client crash 了或者出現了網路分割槽

容錯性:只要大部分 redis 節點存活就可以正常提供服務

set resource_name my_random_value nx px 30000

主要依靠上述命令,該命令僅當 key 不存在時(nx保證)set 值,並且設定過期時間 3000ms (px保證),值 my_random_value 必須是所有 client 和所有鎖請求發生期間唯一的,釋放鎖的邏輯是:

if redis.call("get",keys[1]) == ar**[1] then

return redis.call("del",keys[1])

else

return 0

end

上述實現可以避免釋放另乙個client建立的鎖,如果只有 del 命令的話,那麼如果 client1 拿到 lock1 之後因為某些操作阻塞了很長時間,此時 redis 端 lock1 已經過期了並且已經被重新分配給了 client2,那麼 client1 此時再去釋放這把鎖就會造成 client2 原本獲取到的鎖被 client1 無故釋放了,但現在為每個 client 分配乙個 unique 的 string 值可以避免這個問題。至於如何去生成這個 unique string,方法很多隨意選擇一種就行了。

演算法很易懂,起 5 個 master 節點,分布在不同的機房盡量保證可用性。為了獲得鎖,client 會進行如下操作:

得到當前的時間,微秒單位

嘗試順序地在 5 個例項上申請鎖,當然需要使用相同的 key 和 random value,這裡乙個 client 需要合理設定與 master 節點溝通的 timeout 大小,避免長時間和乙個 fail 了的節點浪費時間

當 client 在大於等於 3 個 master 上成功申請到鎖的時候,且它會計算申請鎖消耗了多少時間,這部分消耗的時間採用獲得鎖的當下時間減去第一步獲得的時間戳得到,如果鎖的持續時長(lock validity time)比流逝的時間多的話,那麼鎖就真正獲取到了。

如果鎖申請到了,那麼鎖真正的 lock validity time 應該是 origin(lock validity time) - 申請鎖期間流逝的時間

如果 client 申請鎖失敗了,那麼它就會在少部分申請成功鎖的 master 節點上執行釋放鎖的操作,重置狀態

放鎖操作很簡單,就是依次釋放所有節點上的鎖就行了

如果我們的節點沒有持久化機制,client 從 5 個 master 中的 3 個處獲得了鎖,然後其中乙個重啟了,這是注意整個環境中又出現了 3 個 master 可供另乙個 client 申請同一把鎖!違反了互斥性。如果我們開啟了 aof 持久化那麼情況會稍微好轉一些,因為 redis 的過期機制是語義層面實現的,所以在 server 掛了的時候時間依舊在流逝,重啟之後鎖狀態不會受到汙染。但是考慮斷電之後呢,aof部分命令沒來得及刷回磁碟直接丟失了,除非我們配置刷回策略為 fsnyc = always,但這會損傷效能。解決這個問題的方法是,當乙個節點重啟之後,我們規定在 max ttl 期間它是不可用的,這樣它就不會干擾原本已經申請到的鎖,等到它 crash 前的那部分鎖都過期了,環境不存在歷史鎖了,那麼再把這個節點加進來正常工作。

redLock可靠的分布式鎖

本文是對 martin kleppmann 的文章 how to do distributed locking 部分內容的翻譯和總結,上次寫 redlock 的原因就是看到了 martin 的這篇文章,寫得很好,特此翻譯和總結。感興趣的同學可以翻看原文,相信會收穫良多。開篇作者認為現在 redis ...

分布式 分布式鎖

本質是利用redis的setnx 方法的特性來加鎖,setnx 即key不存在則設定key,否則直接返回false,要求在分布式系統中使用同乙個redis服務,以下提供兩種解決方案 1 直接使用redistemplate 這其實並不能完全保證高併發下的安全問題,因為可能在鎖過期之後該執行緒尚未執行完...

分布式專題 分布式鎖

在傳統的單體應用架構中,遇到併發安全性問題時我們可以通過同步鎖synchronized,同步 塊,reentrantlock等方式都可以解決,但隨著業務的發展,單體應用架構不能滿足龐大的使用者請求量,於是分布式系統應用而生,在分布式系統中,由於每個系統都執行在不同的伺服器上,有著不同的jvm,所以j...