RedLock是什么四苇?
RedLock是基于redis實(shí)現(xiàn)的分布式鎖孝凌,它能夠保證以下特性:
互斥性:在任何時候,只能有一個客戶端能夠持有鎖月腋;
避免死鎖:當(dāng)客戶端拿到鎖后胎许,即使發(fā)生了網(wǎng)絡(luò)分區(qū)或者客戶端宕機(jī),也不會發(fā)生死鎖罗售;(利用key的存活時間)
容錯性:只要多數(shù)節(jié)點(diǎn)的redis實(shí)例正常運(yùn)行辜窑,就能夠?qū)ν馓峁┓?wù),加鎖或者釋放鎖寨躁;
而非redLock是無法滿足互斥性的穆碎,上面已經(jīng)闡述過了原因。
RedLock算法
假設(shè)有N個redis的master節(jié)點(diǎn)职恳,這些節(jié)點(diǎn)是相互獨(dú)立的(不需要主從或者其他協(xié)調(diào)的系統(tǒng))所禀。N推薦為奇數(shù)~
客戶端在獲取鎖時,需要做以下操作:
獲取當(dāng)前時間戳放钦,以微妙為單為色徘。
使用相同的lockName和lockValue,嘗試從N個節(jié)點(diǎn)獲取鎖操禀。(在獲取鎖時褂策,要求等待獲取鎖的時間遠(yuǎn)小于鎖的釋放時間,如鎖的lease_time為10s颓屑,那么wait_time應(yīng)該為5-50毫秒斤寂;避免因?yàn)閞edis實(shí)例掛掉,客戶端需要等待更長的時間才能返回揪惦,即需要讓客戶端能夠fast_fail遍搞;如果一個redis實(shí)例不可用,那么需要繼續(xù)從下個redis實(shí)例獲取鎖)
當(dāng)從N個節(jié)點(diǎn)獲取鎖結(jié)束后器腋,如果客戶端能夠從多數(shù)節(jié)點(diǎn)(N/2 + 1)中成功獲取鎖溪猿,且獲取鎖的時間小于失效時間钩杰,那么可認(rèn)為,客戶端成功獲得了鎖诊县。(獲取鎖的時間=當(dāng)前時間戳 - 步驟1的時間戳)
客戶端成功獲得鎖后榜苫,那么鎖的實(shí)際有效時間 = 設(shè)置鎖的有效時間 - 獲取鎖的時間。
客戶端獲取鎖失敗后翎冲,N個節(jié)點(diǎn)的redis實(shí)例都會釋放鎖垂睬,即使未能加鎖成功。
為什么N推薦為奇數(shù)呢抗悍?
原因1:本著最大容錯的情況下驹饺,占用服務(wù)資源最少的原則,2N+1和2N+2的容災(zāi)能力是一樣的缴渊,所以采用2N+1赏壹;比如,5臺服務(wù)器允許2臺宕機(jī)衔沼,容錯性為2蝌借,6臺服務(wù)器也只能允許2臺宕機(jī),容錯性也是2指蚁,因?yàn)橐蟪^半數(shù)節(jié)點(diǎn)存活才OK菩佑。
原因2:假設(shè)有6個redis節(jié)點(diǎn),client1和client2同時向redis實(shí)例獲取同一個鎖資源凝化,那么可能發(fā)生的結(jié)果是——client1獲得了3把鎖稍坯,client2獲得了3把鎖,由于都沒有超過半數(shù)搓劫,那么client1和client2獲取鎖都失敗瞧哟,對于奇數(shù)節(jié)點(diǎn)是不會存在這個問題。