Redis分布式鎖如何設(shè)置超時時間
Redis分布式鎖設(shè)置超時時間
Redis分布式鎖主要依靠Redis服務(wù)來完成,我們的應(yīng)用程序其實是Redis節(jié)點的客戶端,一旦客戶端沒有釋放鎖,服務(wù)端就會一直持有這個鎖,其他進程中的線程就無法獲取到這把鎖,于是就會發(fā)生鎖死的情況。
所以我們在使用Redis分布式鎖的時候,務(wù)必要設(shè)置鎖的過期時間。
主要基于下面兩點:
網(wǎng)絡(luò)抖動
客戶端A中的一個線程獲取到了鎖,然后執(zhí)行finally中的釋放鎖的代碼時,這時候網(wǎng)絡(luò)出問題了,導(dǎo)致客戶端A沒有成功釋放鎖。此時對于redis服務(wù)端來說,它會一直把鎖給客戶端A,這樣的話其他客戶端自然也就不能獲取到這個鎖。
如果是設(shè)置了過期時間的話,即使客戶端和服務(wù)端的網(wǎng)絡(luò)不通了,服務(wù)端依然在進行時間的計算,時間到了直接把鎖釋放掉,等網(wǎng)絡(luò)通了,不影響其他客戶端獲取鎖。
Redis宕機
客戶端A獲取到了鎖,Redis服務(wù)器突然宕機,鎖沒有釋放。等到Redis再次恢復(fù)的時候,Redis服務(wù)端還會把鎖給到客戶端A,這樣也會發(fā)生鎖死的情況。
如果是設(shè)置了過期時間的話,服務(wù)器恢復(fù)后就會繼續(xù)倒計時,時間到了服務(wù)器自動把鎖釋放,其他客戶端也就可以嘗試去獲取鎖了。
Redis分布式鎖的超時問題
Redis的分布式鎖并不能解決超時問題,如果在加鎖和釋放鎖之間的邏輯執(zhí)行得太長,以至于超出了鎖的超時限制,就會出現(xiàn)問題,因為這時候第一個線程持有的鎖過期了,臨界區(qū)的邏輯還沒有執(zhí)行完,而同時第二個線程就提前持有了這把鎖,導(dǎo)致臨界區(qū)代碼不能得到嚴(yán)格串行執(zhí)行。
為了避免這個問題,分布式鎖不要用于較長時間的任務(wù),如果真的偶爾出現(xiàn)了問題,造成的數(shù)據(jù)小錯亂,可能需要人工介入解決。
有一個稍微安全一點的方案,是將set指令的value參數(shù)設(shè)置為一個隨機數(shù),釋放鎖時先匹配隨機數(shù)是否一致,然后在刪除key,這是為了確保當(dāng)前線程占有的鎖不會被其他線程釋放,除非這個鎖是自動超時,但是匹配value,和刪除ke y不是一個原子操作,所以只是相對安全。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于Redis6.2.6版本部署Redis?Cluster集群的問題
這篇文章主要介紹了基于Redis6.2.6版本部署Redis?Cluster集群,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-04-04
為何Redis使用跳表而非紅黑樹實現(xiàn)SortedSet
本篇文章主要介紹了為何Redis使用跳表而非紅黑樹實現(xiàn)SortedSet,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
Redis結(jié)合 Docker 搭建集群并整合SpringBoot的詳細(xì)過程
這篇文章主要介紹了Redis結(jié)合Docker搭建集群并整合SpringBoot的詳細(xì)過程,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06

