Redis分布式鎖

2021-09-25 23:58:39 字數 2109 閱讀 6322

redis的常見使用場景有這麼幾種:

這裡我們主要談redis分布式鎖的實現。

分布式鎖主要是為了解決以下幾個問題:

互斥性:多個機器不能同時獲得鎖,同一時刻只有一台機器占有鎖

安全性:保證加鎖和解鎖都是同一臺機器,不能誤釋放別人的鎖

死鎖:節點故障,但是一直占有鎖未釋放,其他節點一直加鎖失敗

容錯:乙個節點故障,保證其他節點可以釋放和獲取到鎖

redis是通過setnx命令來加鎖

setnx key value

當key不存在時,設定成功返回1;

當key存在,設定失敗返回0

這裡在加鎖時一定要設定過期時間,避免乙個節點down掉產生死鎖。

在釋放鎖時我們很多時候會直接del key,但是這樣是不安全的,可能會釋放不該釋放的鎖

因此我們要合理設定過期時間 && 釋放前進行判斷

鎖的過期時間設定合理,不應該太長或太短,鎖的過期時間過長影響新的執行緒重新獲得鎖的流程,影響業務響應時間,太短導致業務未執行完,鎖自動釋放,另乙個執行緒獲得鎖,重新開始執行邏輯,這就間接要求業務保證冪等性,非冪等性的業務會影響資料一致性。

針對這種情況解決方案:守護執行緒為鎖延長過期時間

value是加鎖的唯一標記,它的的值我們可以設定成機器的唯一標示,加鎖解鎖保證在同一臺機器進行。

//release

if c.get(mylock) == myvalue

但是判斷和刪除也分兩步,不是原子操作,存在判斷後鎖過期,另乙個執行緒獲得鎖,然後誤釋放鎖。

使用lua指令碼 原子操作

string luascript = "if redis.call('get',keys[1]) == ar**[1] then return redis.call('del',keys[1]) else return 0 end"

ok,err := c.eval(luascript,mylock,myvalue).result()

官方在redis2.6.12之後就支援這樣的做法:

官方提供的防止死鎖的做法是這樣的:

進行setnx操作,key為你加的鎖,value為當前的時間戳加上鎖的過期時間,並不給鎖加真正的過期時間。

setnx lock.foo

golang的**實現:

//trylock

func trylock(lock string, expiretime time.duration) (bool)

time.sleep(1)

} return true

}//release

func releaselock(lock string, expiretime time.duration)

}

存在兩個問題:

在鎖競爭較高的情況下,會出現value不斷被覆蓋,但是沒有乙個client獲取到鎖

在獲取鎖的過程中不斷的修改原有鎖的資料,設想一種場景c1,c2競爭鎖,c1獲取到了鎖,c2鎖執行了getset操作修改了c1鎖的過期時間,如果c1沒有正確釋放鎖,鎖的過期時間被延長,其它client需要等待更久的時間

這裡我個人更推薦使用lua指令碼+redis分布式鎖結合的方式,這也是目前很多人在使用的方式。

上面描述的是單點情況,若在redis集群環境依然存在問題:

由於redis集群資料同步為非同步,假設在master節點獲取到鎖後未完成資料同步情況下master節點crash,此時在新的master節點依然可以獲取鎖,所以多個client同時獲取到了鎖。

解決方案:

redlock演算法,set向多半節點傳送命令,過半節點成功即為成功,釋放時想全部節點傳送。

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不存在。如給定的...