溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

用Redis實(shí)現(xiàn)分布式鎖的方案

發(fā)布時間:2021-09-10 10:12:22 來源:億速云 閱讀:112 作者:chen 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“用Redis實(shí)現(xiàn)分布式鎖的方案”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“用Redis實(shí)現(xiàn)分布式鎖的方案”吧!

       在實(shí)際項(xiàng)目開發(fā)中經(jīng)常會遇到這樣一個業(yè)務(wù)場景:如果同一臺機(jī)器有多個線程搶奪同一個共享資源,同一個線程多次執(zhí)行會出現(xiàn)異常,這種情況下就會出現(xiàn)非線程安全。我們解決方法通常使用鎖來解決。但是如果有多臺機(jī)器呢?這時候我們通常使用分布式鎖來解決分布式環(huán)境下共享資源的同步問題。實(shí)現(xiàn)分布式鎖常見有Redis,zookeeper等,今天主要就是講講如何使用Redis實(shí)現(xiàn)分布式鎖。

      使用Redis實(shí)現(xiàn)分布式鎖的方案其實(shí)很簡單,首先我們先實(shí)現(xiàn)一個方案一:每次執(zhí)行請求的時候,機(jī)器先查詢Redis中是否存在分布式鎖的key,如果不存在鎖的key,就以該鎖為key,value取隨機(jī)數(shù)寫入到Redis中,然后開始執(zhí)行請求。

      方案一看起來很簡單,但是這樣的處理邏輯不可避免的存在兩個致命的BUG:第一:如果一個進(jìn)程成功取到鎖,但是這時候這個機(jī)器出現(xiàn)故障宕機(jī)了,分布式的鎖沒有得到釋放,就造成了死鎖的產(chǎn)生了。第二:如果同一時間存在兩個機(jī)器同時查詢Redis,都發(fā)現(xiàn)Redis不存在鎖的key,于是都成功獲得了鎖。

     這時候我們可以這么處理改善方案一實(shí)現(xiàn)方案二:Redis有提供一個原子寫入操作的命令:setnx,setnx只有在鎖的key不存在的情況下才允許設(shè)置key值,所以說問題2同一個鎖在同一時間可能會被不同機(jī)器獲取到的問題就可以得到解決,而且setnx命令可以設(shè)置key值的超時時間,所以在寫入鎖的key時可以為鎖設(shè)置一個超時時間,如果超過超時時間鎖還未釋放就會釋放,則其他機(jī)器在key釋放后也可以繼續(xù)寫入key占有鎖執(zhí)行對應(yīng)的請求。這樣問題1機(jī)器宕機(jī)造成鎖無法及時釋放的問題也因此迎刃而解。

     但是這又造成了另外一個潛在的問題:如果某個機(jī)器執(zhí)行耗時操作,超時時間過去了請求還未執(zhí)行完,鎖就會被釋放掉被新的機(jī)器占有,等耗時任務(wù)結(jié)束時執(zhí)行釋放鎖的操作,這時候釋放的鎖不是自己的鎖而是已經(jīng)被其他機(jī)器占有的鎖。

     這時候我們可以將方案再做適當(dāng)?shù)男薷淖兂煞桨溉寒?dāng)某個機(jī)器占有鎖并在Redis中設(shè)置key時,將value設(shè)置為隨機(jī)數(shù),在請求處理完畢需要釋放鎖之前加上一步操作:判斷keyvalue值是否等于之前設(shè)置的隨機(jī)數(shù),如果是代表這個鎖占有者還是自己,就可以執(zhí)行釋放鎖操作,否則代表鎖已經(jīng)被別人占有,不能執(zhí)行釋放鎖操作,這樣就可以解決可能誤操作釋放他人鎖的問題。但是由于查詢和釋放鎖的操作非原子性的,所以可能出現(xiàn)一種情況:在查詢key時發(fā)現(xiàn)keyvalue和機(jī)器本身設(shè)置的一直,但是還沒來得急釋放鎖時,鎖過期被釋放了,這時候執(zhí)行釋放鎖操作就會導(dǎo)致釋放的依舊是其他機(jī)器占有的鎖,所以我們方案三需要進(jìn)一步的改進(jìn),也就是我們必須要保證查詢鎖和釋放鎖這兩步操作必須是原子性的,這時候我們就需要使用另一種方式:引入Jedis,使用Lua腳本將查詢鎖和釋放鎖的兩部分邏輯寫成腳本,于是Redis執(zhí)行Lua腳本時,其他機(jī)器的所有命令都必須等到Lua腳本執(zhí)行結(jié)束才能執(zhí)行,所以不可能存在查詢鎖結(jié)束還未釋放就被其他機(jī)器占領(lǐng)的情況。  

       到這里我們介紹完了如何使用Redis實(shí)現(xiàn)分布式鎖,但是這是基于單機(jī)部署,如果Redis是使用多機(jī)部署,每個主節(jié)點(diǎn)還有有子節(jié)點(diǎn),由于Redis主從復(fù)制是異步操作,所在上述方案肯定會出現(xiàn)問題的,多機(jī)部署可以采用Redission實(shí)現(xiàn)分布式鎖,這是官方提供的組件,如果感興趣可以自己閱讀下文檔:
https://github.com/redisson/redisson
 

到此,相信大家對“用Redis實(shí)現(xiàn)分布式鎖的方案”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI