鍍金池/ 問答/人工智能  Linux  數(shù)據(jù)庫/ redis 鎖超時(shí)自動(dòng)釋放 導(dǎo)致的多客戶端同時(shí)獲取鎖 如何解決

redis 鎖超時(shí)自動(dòng)釋放 導(dǎo)致的多客戶端同時(shí)獲取鎖 如何解決

假設(shè)
客戶端1:

通過 `SET lock 123 NX PX 30000`獲取了鎖
執(zhí)行時(shí)間超時(shí)太長, 鎖自動(dòng)失效
但此時(shí)客戶端1還是在繼續(xù)執(zhí)行
....

客戶端2:

在客戶端1超時(shí)導(dǎo)致鎖自動(dòng)失效后, 它立刻獲取了鎖 `SET lock 456 NX PX 30000`

此時(shí)就有兩個(gè)客戶端同時(shí)都能執(zhí)行那些只有獲取了鎖之后才能執(zhí)行的內(nèi)容!!!

回答
編輯回答
愿如初

使用 WATCH/MULTI/EXEC ,watch能保證 MULTI 和 EXEC 之間的命令只有在watch的值沒有變化才執(zhí)行成功,見官方文檔https://redis.io/topics/trans...。

所以一般這個(gè)鎖的值要在整個(gè)系統(tǒng)保持唯一。

2017年5月20日 22:31
編輯回答
寫榮

使用redis做鎖時(shí),不應(yīng)該完全使用超時(shí)時(shí)間來控制鎖是否被占用。
在邏輯執(zhí)行完后,應(yīng)該立刻清掉該key釋放掉鎖,一般寫在finally塊中保證能夠釋放。
而超時(shí)時(shí)間的設(shè)置,只是為了萬一在邏輯執(zhí)行過程中系統(tǒng)直接掛掉,沒能在最后手動(dòng)釋放鎖,又沒有超時(shí)時(shí)間,就會導(dǎo)致該鎖永遠(yuǎn)被占用。
所以,超時(shí)時(shí)間可以根據(jù)該邏輯的執(zhí)行時(shí)間多加大一點(diǎn)進(jìn)行設(shè)置,然后在邏輯執(zhí)行完之后手動(dòng)解鎖。

2017年12月3日 23:09
編輯回答
安淺陌

鎖超時(shí)被釋放不是很正常嗎。。 因?yàn)槲覜]有用過redis,所以對于樓上說的超時(shí)如何避免我不知道。。但是從分布式系統(tǒng)的角度來分析這個(gè)問題,鎖其實(shí)就等于租約,誰從redis得到了租約,誰就是集群的leader,執(zhí)行一些follower不能做的操作,但是呢,leader總是會由于種種問題(網(wǎng)絡(luò)、gc)無法及時(shí)續(xù)租,導(dǎo)致超時(shí),這時(shí)候另外一個(gè)follower進(jìn)而得到鎖,導(dǎo)致集群雙主。 所以問題的性質(zhì)就變成了分布式情況下如何避免多主(或腦裂)。常用的做法就是fencing機(jī)制,如kafka的epoch。樓主可以試下

2018年4月24日 21:29