redis實現分布式鎖 乞丐版

2021-10-06 16:59:19 字數 1637 閱讀 9389

今天記錄一下redis實現分布式鎖,寫這個話題我猶豫了很久,因為這個實現雖然很容易,但是有很多細節需要注意,一不小心就死鎖,但是仔細一想好像也沒幾個人看我的文章,就當給自己做個筆記吧!大佬們要是發現那兒思路有問題,期待你能指出來哦,在生產環境下最好用redisson,別傻傻的自己實現了

在單機下我們的多執行緒爭搶資源是很好解決的,無非就是加鎖,reentrantlock,synchronized等等都行,但是在多執行緒的情況下,他們已經不是同乙個jvm了,他們是不可能在自己的jvm鎖到同乙個物件的,如圖:

所以,在分布式系統中我們需要的是這樣乙個架構:

這兒的中介軟體我們今天就是用的redis,後面可能會再寫一下zookeeper實現分布式鎖

我們只需要知道的幾個很簡單的redis命令:

set示例: set name xiaoz ex 5 nx 解釋: 設定name欄位的值為xiaoz,失效時間為5秒,如果不存在這個key的話

expire示例: expire name 5 解釋: 設定name欄位的超時時間為5秒

del示例: del name 解釋: 刪除name欄位

假設現在兩台機器一共8個執行緒都在爭搶鎖

加鎖

那麼他們怎麼才能算搶到鎖呢?

redis發揮作用了,set加上nx引數能保證只有一次set操作能成功,為什麼呢?我們暫且可以將redis理解為單執行緒,所以進來的8個操作是排好隊的,聽大佬們說好像redis並不完全都是單執行緒,這兒等我了解後再記錄吧。(小本本記上)

set lock 只有自己知道的乙個值,可以是隨機數 ex 5 nx

既然只有乙個操作能成功的話,那不就不用擔心資源爭搶的問題了,不就實現了分布式加鎖了嗎?

網上很多方案是用setnx加expire,其實這兒會有一點問題,因為他不是原子性的,如果在setnx之後剛好宕機了,那麼這個鎖就沒有失效時間了,造成死鎖,當然,這兒可以用lua指令碼操作,lua指令碼是具備原子性的

解鎖

解鎖直接使用del將lock這個鍵刪除不就解鎖了嗎,不過要注意的是,我們需要判斷一下這個鎖是不是自己的,怎麼判度就是去對比value,這個value只有自己知道,如果一樣就刪除,那麼需要先判斷一下,那麼又出現了原子問題,這兒我們可以使用lua指令碼實現,因為之前說過lua指令碼是具備原子性的

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

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

else

return 0

end

分布式鎖 使用Redis實現分布式鎖

關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...

redis實現分布式鎖

隨便 系統越來越大,各功能模組除了垂直切割以外,同時也得做集群處理,那麼問題來了,在多執行緒情況下對於資源的競爭就需要乙個統一的訪問限制。以選課系統為例子,集群中各節點對課程可選數量同時操作,這裡就需要同步了,否則會導致最後選到的數量比可選的數量大,這裡我們的分布式鎖就派上用場了。利用redis來實...

redis實現分布式鎖

分布式鎖可以基於很多種方式實現,比如zookeeper redis.不管哪種方式,他的 基本原理是不變的 用乙個狀態值表示鎖,對鎖的占用和釋放通過狀態值來標識。1 使用redis的setnx命令實現分布式鎖 1 實現的原理 redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多客戶...