《redis in action》Redis分布式鎖寫點筆記關(guān)注共 1834字,需瀏覽 4分鐘 ·2021-04-22 22:39 這塊作者還是大概得將書中的內(nèi)容進(jìn)行一下翻譯,首先為啥要用redis分布式鎖。我們在之前學(xué)redis事務(wù)的時候說redis提供了watch/mutli/exec機(jī)制,其中的watch是樂觀鎖。也就是通過監(jiān)聽某個數(shù)據(jù)的變動來做出相應(yīng)的改變。當(dāng)時我們也說了redis的watch樂觀鎖為啥不像關(guān)系型數(shù)據(jù)庫那樣直接禁止別其他客戶端修改的問題。Redis更多的還是基于其效率設(shè)計,因此通過盡可能快的通知客戶端去維護(hù)數(shù)據(jù)的安全性,通過watch的樂觀鎖和mutli/exec事務(wù)來看。確實可以直接做分布式鎖,為啥可以做這件事的原因是watch命令的監(jiān)聽特性會一直持續(xù)到exec的執(zhí)行,如果watch的鍵值發(fā)生變化,那么watch后邊的事務(wù)是不會執(zhí)行的。但是我們必須要保持我們的事務(wù)不會出現(xiàn)指令性質(zhì)的錯誤,這塊我們之前說過redis事務(wù)本身和關(guān)系型數(shù)據(jù)庫事務(wù)不一樣,執(zhí)行出錯期間不能回滾。使用watch去做分布式鎖的過程大概如下,這里直接截書中的python代碼了:使用watch做分布式鎖的問題在于效率問題,我們說watch的樂觀鎖為了就是及時通知客戶端,然后讓其發(fā)起重試,所以當(dāng)加鎖壓力比較大的時候重試就非常常見。加之watch/multi/exec的執(zhí)行過程,所以時間消耗非常明顯。書中專門還做了相關(guān)的測試。具體如下:我們看到隨著買賣的人員越來越多,單筆交易所發(fā)生的重試次數(shù)不斷提升,而且平均等待時間也不斷增長??紤]到重試代碼反復(fù)運(yùn)行以及重試的網(wǎng)絡(luò)時間消耗以及相關(guān)watch事務(wù)通信,因此我們考慮是否有一種可以直接類似if這樣的條件語句來做這件事,相當(dāng)于將復(fù)雜的過程簡單化。這塊還真有,redis提供了setnx命令,這個命令是什么意思吶?悄悄告訴你,這個命令就是說如果key不存在的時候,我才給這個key設(shè)置一個值?;诖?,我們數(shù)以百計得redis客戶端有救了,各個客戶端只需要這個命令就判斷是否已經(jīng)被加鎖,時候獲取了鎖。我們看下邊的代碼:這塊在獲取鎖的時候,設(shè)置一個時間限制。超過這個時間我們就當(dāng)作獲取鎖失敗了,那么咋就發(fā)起重試,但是咋并沒有建立事務(wù)啥的,因為太麻煩了。當(dāng)我們獲取鎖之后我們將我們的鎖的唯一標(biāo)識返回,為啥要返回的原因:方便進(jìn)行鎖釋放,您可能會問直接刪除key不就行了么,咋那么麻煩,這塊您需要考慮多次釋放鎖以及鎖已經(jīng)被其他進(jìn)程獲取,然后當(dāng)前進(jìn)程把其他進(jìn)程的鎖釋放導(dǎo)致其他進(jìn)程業(yè)務(wù)出現(xiàn)錯誤。除此之外我們還要考慮在我們釋放鎖的瞬間,其他進(jìn)程修改了鎖或者破壞了鎖,因為這是不允許的,那會影響我們當(dāng)前的業(yè)務(wù)正常。那么我們就要保證我們釋放鎖得時候這個鎖要是正常的,所以這塊用了上邊我們說的效率比較低的watch樂觀鎖+事務(wù)的鎖機(jī)制。通過上述的代碼,書中也做了相關(guān)的測試工作。我們看到通過使用setnx命令做的鎖機(jī)制相對于watch樂觀鎖+事務(wù)的性能提升相當(dāng)?shù)拿黠@,對比太明顯,直接貼圖吧。當(dāng)然上述的講述,我們并沒有考慮鎖超時的問題。也就是說當(dāng)前進(jìn)程釋放鎖失敗了,或者直接宕機(jī)等比較嚴(yán)重的問題導(dǎo)致setnx的key沒有被清理。那么其他的進(jìn)程必然無法獲得鎖,必然導(dǎo)致一個老鼠害了一鍋湯的問題。這塊先不討論鎖超時的問題,下次再聊。除此之外分布式鎖還有哪些問題?書中總結(jié)了4點:第一:一個進(jìn)程獲得鎖,操作了數(shù)據(jù)。但是這個過程花費了太久時間,然后這個鎖考慮到鎖自動超時的問題,被自動釋放了。但是這個進(jìn)程并不知道它已經(jīng)釋放了鎖。所以潛在的問題是這個自動超時時間設(shè)置多大合適吶?是不是一臉問號,總不能寫死吧。第二:一個進(jìn)程獲得鎖,然后操作數(shù)據(jù),但是花了太久時間然后宕機(jī)了。其他進(jìn)程想要獲得鎖,但是不知道到底是哪個進(jìn)程一直持有鎖,所以一直傻傻的在哪里等,黃花菜都涼了也沒音信。第三:一個進(jìn)程獲得了鎖,但是鎖超時了,其他進(jìn)程獲取了鎖。就這樣這個鎖一直超時,完事導(dǎo)致大量業(yè)務(wù)沒有真正的實現(xiàn)鎖,最終一大批臟數(shù)據(jù)。第四:第一和第三個問題組合,導(dǎo)致很多進(jìn)程都堅信自己獲取到了鎖。個人感覺這四個問題其實還是一個關(guān)鍵,就是鎖超時時間大小如何動態(tài)修改的問題,如果此問題解決了那么這四個問題就不是問題。OK,本次文章就到這里了,天晚了,聽個歌兒吧,晚安! 瀏覽 62點贊 評論 收藏 分享 手機(jī)掃一掃分享分享 舉報 評論圖片表情視頻評價全部評論推薦 《redis in action》Redis鎖超時和重入鎖寫點筆記0細(xì)說Redis分布式鎖程序員考拉0細(xì)說Redis分布式鎖每天曬白牙0細(xì)說Redis分布式鎖程序員面試吧0Redis實現(xiàn)分布式鎖程序媛和她的貓0聊聊 Redis 分布式鎖0. 前言 Redis 是日常開發(fā)中經(jīng)常使用到的中間件,以優(yōu)秀的性能著稱。但是 Redis 分布式鎖可以說是飽受爭議,很多人認(rèn)為 Redis 并不適合作為分布式鎖。它確實存在著一些問題,今天我準(zhǔn)備聊一聊 Redis 分布式鎖如何實...細(xì)說Redis分布式鎖公眾號程序猿DD0Redis in ActionRedis in Action0Redis in ActionRedis is an innovative data tool that offers more 《redis in action》redis事務(wù)寫點筆記0點贊 評論 收藏 分享 手機(jī)掃一掃分享分享 舉報