Redis實現分布式鎖

2021-09-27 10:30:44 字數 1254 閱讀 3726

在jvm同乙個程序內的執行緒

單程序的併發場景,我們可以使用語言和類庫提供的鎖如sychronized和reentranlock,對於部分不是的場景,我們需要使用分布式鎖。

分布式鎖的實現方式

加鎖 setnx(key,1)

當乙個執行緒執行setnx返回1,說明key原本不存在,該執行緒成功得到了鎖,當乙個執行緒執行setnx返回0,說明key已經存在,該執行緒搶鎖失敗。

解鎖 del(key)

當得到鎖的執行緒執行完任務,需要釋放鎖,以便其他執行緒進入,釋放鎖的簡單方式執行del指令。

鎖超時 (key,30)

如果乙個得到鎖的執行緒在執行任務的過程中掛掉,來不及顯式地釋放鎖,這塊資源將會永遠被鎖住,別的執行緒再也別想進來。

if

(setnx

(key,1)

==1)finally

}

setnx和expire之間不是原子性操作,如果執行完setnx,節點宕機了,那麼鎖就永遠得不到釋放。在redis2.6.12提供了set指令增加了可選引數。set(key,1,30,nx)

del導致誤刪

如果某些原因導致執行緒a執行很慢,過了30秒都還沒有執行完,這時候鎖過期自動釋放,執行緒b得到了鎖,隨後執行緒a執行完任務,執行緒a接著執行del釋放鎖,但這時候b還沒有執行完,執行緒a釋放的是執行緒b加的鎖。

解決方法:在del釋放鎖之前加乙個判斷,驗證當前的鎖是不是自己加的,可以在加鎖的時候那當前執行緒id當做value,並在刪除之前驗證key對應的value是不是自己的執行緒id。

//加鎖

string threadid=thread.

currentthread()

.getid;

set(key,threadid,

30,nx)

;//解鎖

if(threadid.

equals

(redisclient.

get(key)))

出現併發的可能性

雖然我們避免了執行緒a誤刪掉key的情況,但是同一時間有a,b兩個執行緒在訪問**塊,仍然使不完美的。我們可以獲得鎖的執行緒開啟乙個守護執行緒,用來給快要過期的鎖續航。

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

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

redis實現分布式鎖

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

redis實現分布式鎖

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