redis分布式鎖原理

2021-10-03 06:27:18 字數 1672 閱讀 9097

以redisson為例

rlock lock = redissonclient.

getlock

(key)

; lock.

lock

(timeoutsecond, timeunit.seconds)

;

原則:1.自己加的鎖自己釋放,2.鎖到期了業務沒執行完還需續期

"if (redis.call('exists', keys[1]) == 0) then "

+"redis.call('hset', keys[1], ar**[2], 1); "

+"redis.call('pexpire', keys[1], ar**[1]); "

+"return nil; "

+"end; "

+"if (redis.call('hexists', keys[1], ar**[2]) == 1) then "

+"redis.call('hincrby', keys[1], ar**[2], 1); "

+"redis.call('pexpire', keys[1], ar**[1]); "

+"return nil; "

+"end; "

+"return redis.call('pttl', keys[1]);"

keys[1]代表加鎖的key,ar**[2]代表的是加鎖的客戶端id,ar**[1]代表的鎖的生存時間

如果其它客戶端來加鎖,第乙個if會失敗,然後第二個if,然後再hash結構中判斷是否存在客戶端2的id,因為不含有,所以會走最後return返回過期時間,然後客戶端2會進入while迴圈,不停的嘗試加鎖。

如果客戶端超過生存時間還想持有鎖,怎麼辦?

加鎖成功同時會啟動乙個後台執行緒檢查,如果客戶端還持有鎖就會不斷延長生存時間,預設是10s一次

進入第二個if,會把value + 1

"if (redis.call('hexists', keys[1], ar**[3]) == 0) then " +

"return nil;" +

"end; " +

"local counter = redis.call('hincrby', keys[1], ar**[3], -1); " +

"if (counter > 0) then " +

"redis.call('pexpire', keys[1], ar**[2]); " +

"return 0; " +

"else " +

"redis.call('del', keys[1]); " +

"redis.call('publish', keys[2], ar**[1]); " +

"return 1; "+

"end; " +

"return nil;"

先把鎖裡的計數減一,然後再刪除

master節點宕機,salve變成master,資料還沒來得及同步,這樣其他客戶端就有可能完成加鎖。就會導致多個客戶端同時持有了鎖。

redis分布式鎖原理

舉例子 秒殺方式看醫生,乙個人看5min 1.第一次只允許乙個人直接進行來,x10 00 00進去了,setnx roomid,now 5min 出來時間假如是10 05 00 2.時間到了10 05 00,3個人同時進來,需要去看牆上的鐘錶,乙個人乙個的看 a進入病房看到,看到鐘錶時間10 05 ...

redis分布式鎖

redis分布式鎖 直接上 我寫了四個redis分布式鎖的方法,大家可以提個意見 第一種方法 redis分布式鎖 param timeout public void lock long timeout thread.sleep 100 catch exception e override publi...

Redis分布式鎖

分布式鎖一般有三種實現方式 1.資料庫樂觀鎖 2.基於redis的分布式鎖 3.基於zookeeper的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...