redis分布式鎖

2021-09-17 08:50:41 字數 1239 閱讀 9188

原文:

redis 分布式鎖的實現方法,表面上看很簡單。

指定乙個key, 獲取鎖 ,查詢一下redis中 這個key有沒有值,沒有,就設定,獲取鎖就成功了,

釋放鎖,就刪除這個key

問題:併發判斷redis中 都沒有key, 同時去加鎖,會出現覆蓋問題

解決: 使用 setnx 命令,不存在才設定,只有乙個能設定鎖成功

問題: 執行緒還未來得及釋放鎖,程式奔潰了,其他的都被阻塞了。

解決: 對加入的鎖,設定乙個過期時間。

問題: setnx 和 expire 新增和設定過期不是原子操作,還是會出現鎖無法釋放

解決: redis2.8以後新增了指令 set lock:key true ex 5 nx

使用lua指令碼設定,是比較通用的方式

string script = "local rs=redis.call('setnx',keys[1],ar**[1]);if(rs<1) then return 'f';end;redis.call('expire',keys[1],tonumber(ar**[2]));return 's';";

jedis jedis = shardedjedis.getshard(rediskey);

object result = jedis.evalsha(script, keys, args);

if ("s".equals(result))

出處:

問題: 釋放鎖的時候,鎖過期,被其他執行緒獲取到鎖,然後這個執行緒執行後釋放了鎖

解決: 加鎖的時候設定乙個隨機值,釋放鎖的時候,先取出來判斷 這個值是否有變更,如果變更了說明鎖已經被其他人占有了,沒有變更,釋放鎖。 這個地方 判斷和 釋放鎖,不是原子性,需要使用lua指令碼 保證原子性

以上都針對的是 單機的情況。

如果 有備機切換的話,這種情況就有問題了。

那怎麼辦?

redisson 實現方式(紅鎖 redlock)

github redisson

org.redisson

redisson

3.9.0

org.redisson

redisson

2.14.0

redlock 實現的演算法規則

加鎖時,給redis集群的 每乙個master 都加鎖。

加鎖成功的條件:a. 超過半數的機器加鎖成功,b. 總加鎖時間,小於單個鎖超時時間

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的分布式鎖.首先,為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件 互斥性。在任意時刻,只有乙個客戶端能持有鎖。不會發生死鎖。即使有乙個客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保...

redis分布式鎖

使用redis的setnx命令實現分布式鎖 redis為單程序單執行緒模式,採用佇列模式將併發訪問變成序列訪問,且多個客戶端對redis的連線並不存在競爭關係。redis的setnx命令可以方便的實現分布式鎖。setnx key value 將key的值設為value,當且僅當key不存在。如給定的...