Redis的分布式鎖-翻譯:Distributed locks with Redis – Redis
分布式鎖在許多環(huán)境中是一種非常有用的原素剃幌,不同的進(jìn)程必須以相互排斥的方式操作共享資源歹撒。
有許多庫(kù)和博文描述了如何用Redis實(shí)現(xiàn)DLM(分布式鎖管理器),但每個(gè)庫(kù)都使用了不同的方法褥芒,而且許多庫(kù)使用的是簡(jiǎn)單的方法宇攻,與稍微復(fù)雜的設(shè)計(jì)所能達(dá)到的效果相比抱虐,保障較低亩鬼。
本頁(yè)試圖提供一種更規(guī)范的算法來(lái)實(shí)現(xiàn)Redis的分布式鎖。我們提出了一種算法烘挫,叫做Redlock诀艰,它實(shí)現(xiàn)了一個(gè)DLM,我們認(rèn)為它比虛構(gòu)的單實(shí)例方法更安全饮六。我們希望社區(qū)能夠?qū)ζ溥M(jìn)行分析其垄,提供反饋,并將其作為實(shí)現(xiàn)或更復(fù)雜或替代設(shè)計(jì)的起點(diǎn)卤橄。
實(shí)施方案
在描述該算法之前绿满,這里有幾個(gè)已經(jīng)有的實(shí)現(xiàn)的鏈接,可以用來(lái)參考窟扑。
- Redlock-rb(Ruby實(shí)現(xiàn))棒口。還有一個(gè)Redlock-rb的分叉寄月,增加了一個(gè)便于發(fā)布的gem,也許還有更多无牵。
- Redlock-py (Python 實(shí)現(xiàn))。
- Pottery (Python 實(shí)現(xiàn))厂抖。
- Aioredlock (Asyncio Python 實(shí)現(xiàn))茎毁。
- Redlock-php (PHP 實(shí)現(xiàn))。
- PHPRedisMutex (進(jìn)一步的PHP實(shí)現(xiàn))
- cheprasov/php-redis-lock (鎖的PHP庫(kù))
- rtckit/react-redlock (Async PHP 實(shí)現(xiàn))
- Redsync (Go實(shí)現(xiàn)).
- Redisson (Java實(shí)現(xiàn))忱辅。
- Redis::DistLock (Perl 實(shí)現(xiàn))七蜘。
- Redlock-cpp (C++ 實(shí)現(xiàn))。
- Redlock-cs (C#/.NET 實(shí)現(xiàn))墙懂。
- RedLock.net(C#/.NET 實(shí)現(xiàn))橡卤。包括async和鎖的擴(kuò)展支持。
- ScarletLock (C# .NET實(shí)現(xiàn)损搬,可配置數(shù)據(jù)存儲(chǔ))
- Redlock4Net (C# .NET實(shí)現(xiàn))
- node-redlock(NodeJS實(shí)現(xiàn))碧库。包括對(duì)鎖擴(kuò)展的支持。
安全和有效性保證
我們將用三個(gè)屬性來(lái)模擬我們的設(shè)計(jì)巧勤,從我們的角度來(lái)看嵌灰,這三個(gè)屬性是以有效方式使用分布式鎖所需的最低限度的保證。
- 安全屬性颅悉。相互排斥沽瞭。在任何時(shí)候,只有一個(gè)客戶(hù)可以持有一個(gè)鎖剩瓶。
- 有效性屬性A:無(wú)死鎖驹溃。最終總是有可能獲得一個(gè)鎖,即使鎖定資源的客戶(hù)端崩潰或被分割延曙。
- 有效性屬性B:容錯(cuò)豌鹤。只要大多數(shù)Redis節(jié)點(diǎn)是正常的,客戶(hù)端就能夠獲得和釋放鎖搂鲫。
為什么基于故障轉(zhuǎn)移的實(shí)現(xiàn)是不夠的
為了了解我們想要改進(jìn)的地方傍药,讓我們分析一下大多數(shù)基于Redis的分布式鎖庫(kù)的現(xiàn)狀。
使用Redis鎖定資源的最簡(jiǎn)單方法是在一個(gè)實(shí)例中創(chuàng)建一個(gè)密鑰魂仍。這個(gè)鍵通常是在有限的時(shí)間內(nèi)創(chuàng)建的拐辽,使用Redis的過(guò)期功能,所以最終它將被釋放(我們列表中的屬性2)擦酌。當(dāng)客戶(hù)端需要釋放資源時(shí)俱诸,它就會(huì)刪除該密鑰。
表面上看這很好赊舶,但有一個(gè)問(wèn)題:這是我們架構(gòu)中的一個(gè)單一故障點(diǎn)睁搭。如果Redis的主節(jié)點(diǎn)壞了會(huì)怎樣赶诊?好吧,讓我們添加一個(gè)從節(jié)點(diǎn)吧! 并在主節(jié)點(diǎn)不可用的情況下使用它园骆。不幸的是舔痪,這是不可行的。因?yàn)镽edis復(fù)制是異步的锌唾,這樣做我們就不能實(shí)現(xiàn)互斥的安全屬性锄码。
這種模式有一個(gè)明顯的競(jìng)賽條件。
- 客戶(hù)端A獲得了主站的鎖晌涕。
- 在對(duì)鑰匙的寫(xiě)入被傳送到從站之前滋捶,主站崩潰了。
- 從機(jī)被提升為主機(jī)余黎。
- 客戶(hù)端B獲得了A已經(jīng)持有鎖的同一資源的鎖重窟。違反安全規(guī)定!
有時(shí)候,在特殊情況下惧财,比如在故障期間巡扇,多個(gè)客戶(hù)端可以同時(shí)持有鎖,這是完全可以的可缚。如果是這種情況霎迫,你可以使用你的基于復(fù)制的解決方案。否則帘靡,我們建議實(shí)施本文檔中描述的解決方案知给。
單一實(shí)例的正確實(shí)現(xiàn)
在嘗試克服上述單實(shí)例設(shè)置的限制之前,讓我們檢查一下如何在這個(gè)簡(jiǎn)單的情況下正確地實(shí)現(xiàn)它描姚,因?yàn)檫@實(shí)際上是一個(gè)可行的解決方案涩赢,在應(yīng)用中不時(shí)出現(xiàn)的競(jìng)賽條件是可以接受的,而且因?yàn)殒i定到一個(gè)單實(shí)例是我們將用于這里描述的分布式算法的基礎(chǔ)轩勘。
要獲得鎖筒扒,方法是這樣的。
SET resource_name my_random_value NX PX 30000
該命令只在密鑰不存在的情況下設(shè)置(NX選項(xiàng))绊寻,過(guò)期時(shí)間為30000毫秒(PX選項(xiàng))花墩。密鑰被設(shè)置為一個(gè)值 "myrandomvalue"。這個(gè)值在所有客戶(hù)端和所有鎖請(qǐng)求中必須是唯一的澄步。
基本上冰蘑,隨機(jī)值是為了以安全的方式釋放鎖,用一個(gè)腳本告訴Redis:只有當(dāng)它存在并且存儲(chǔ)在鍵上的值正是我期望的值時(shí)村缸,才會(huì)刪除該鍵祠肥。這是由以下Lua腳本完成的。
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
這一點(diǎn)很重要梯皿,以避免刪除由其他客戶(hù)創(chuàng)建的鎖仇箱。例如县恕,一個(gè)客戶(hù)可能獲得了鎖,在某些操作中被阻塞剂桥,時(shí)間超過(guò)了鎖的有效期(鑰匙將過(guò)期的時(shí)間)忠烛,后來(lái)刪除了已經(jīng)被其他客戶(hù)獲得的鎖。僅僅使用DEL是不安全的渊额,因?yàn)橐粋€(gè)客戶(hù)可能會(huì)刪除另一個(gè)客戶(hù)的鎖况木。在上面的腳本中,每個(gè)鎖都有一個(gè)隨機(jī)字符串的 "簽名"旬迹,所以只有當(dāng)它仍然是由試圖刪除它的客戶(hù)端設(shè)置的鎖時(shí)才會(huì)被刪除。
這個(gè)隨機(jī)字符串應(yīng)該是什么求类?我假設(shè)它是來(lái)自/dev/urandom的20個(gè)字節(jié)奔垦,但你可以找到更便宜的方法來(lái)使它對(duì)你的任務(wù)來(lái)說(shuō)足夠獨(dú)特。例如尸疆,一個(gè)安全的選擇是用/dev/urandom作為RC4的種子椿猎,并從中生成一個(gè)偽隨機(jī)流。一個(gè)更簡(jiǎn)單的解決方案是使用具有微秒分辨率的unix時(shí)間的組合寿弱,將其與客戶(hù)的ID連接起來(lái)犯眠,它不那么安全,但在大多數(shù)環(huán)境中可能可以完成任務(wù)症革。
我們用來(lái)作為關(guān)鍵時(shí)間的時(shí)間筐咧,被稱(chēng)為 "鎖的有效性時(shí)間"。它既是自動(dòng)釋放時(shí)間噪矛,也是客戶(hù)端在另一個(gè)客戶(hù)端能夠再次獲得鎖之前執(zhí)行所需操作的時(shí)間量蕊,在技術(shù)上不違反互斥保證,它只限于從獲得鎖的那一刻起的特定時(shí)間窗口艇挨。
所以現(xiàn)在我們有了一個(gè)獲取和釋放鎖的好方法残炮。這個(gè)系統(tǒng),對(duì)一個(gè)由單一的缩滨、總是可用的實(shí)例組成的非分布式系統(tǒng)進(jìn)行推理势就,是安全的。讓我們把這個(gè)概念擴(kuò)展到一個(gè)分布式系統(tǒng)脉漏,在那里我們沒(méi)有這樣的保證苞冯。
Redlock算法
在該算法的分布式版本中,我們假設(shè)我們有N個(gè)Redis主站鸠删。這些節(jié)點(diǎn)是完全獨(dú)立的抱完,所以我們不使用復(fù)制或任何其他隱含的協(xié)調(diào)系統(tǒng)。我們已經(jīng)描述了如何在單個(gè)實(shí)例中安全地獲取和釋放鎖刃泡。我們想當(dāng)然地認(rèn)為巧娱,算法將使用這種方法來(lái)獲取和釋放單實(shí)例中的鎖碉怔。在我們的例子中,我們?cè)O(shè)置了N=5禁添,這是一個(gè)合理的值撮胧,所以我們需要在不同的計(jì)算機(jī)或虛擬機(jī)上運(yùn)行5個(gè)Redis主站,以確保它們會(huì)以一種基本獨(dú)立的方式失敗老翘。
為了獲得鎖芹啥,客戶(hù)端執(zhí)行以下操作。
- 獲取當(dāng)前的時(shí)間铺峭,以毫秒為單位墓怀。
- 依次在所有N個(gè)實(shí)例中獲取鎖蜈膨,在所有實(shí)例中使用相同的鍵名和隨機(jī)值妄呕。在步驟2中,當(dāng)在每個(gè)實(shí)例中設(shè)置鎖時(shí)布持,客戶(hù)端使用一個(gè)與總的鎖自動(dòng)釋放時(shí)間相比很小的超時(shí)來(lái)獲取它莉炉。例如钓账,如果自動(dòng)釋放時(shí)間是10秒,超時(shí)可以在~ 5-50毫秒范圍內(nèi)絮宁。這可以防止客戶(hù)端在試圖與Redis節(jié)點(diǎn)對(duì)話(huà)時(shí)長(zhǎng)時(shí)間受阻:如果一個(gè)實(shí)例不可用梆暮,我們應(yīng)該盡快嘗試與下一個(gè)實(shí)例對(duì)話(huà)。
- 客戶(hù)端通過(guò)從當(dāng)前時(shí)間減去步驟1中獲得的時(shí)間戳绍昂,計(jì)算出獲得鎖所需的時(shí)間啦粹。如果并且只有當(dāng)客戶(hù)端能夠在大多數(shù)實(shí)例(至少3個(gè))中獲取鎖,并且獲取鎖的總時(shí)間小于鎖的有效期治专,鎖才被認(rèn)為是被獲取卖陵。
- 如果鎖被獲取,其有效性時(shí)間被認(rèn)為是初始有效性時(shí)間減去經(jīng)過(guò)的時(shí)間张峰,如步驟3中計(jì)算的那樣泪蔫。
- 如果客戶(hù)端由于某種原因未能獲得鎖(要么它無(wú)法鎖定N/2+1個(gè)實(shí)例,要么有效性時(shí)間為負(fù)數(shù))喘批,它將嘗試解鎖所有的實(shí)例(甚至是它認(rèn)為無(wú)法鎖定的實(shí)例)撩荣。
該算法是異步的嗎?
該算法依賴(lài)于這樣的假設(shè):雖然沒(méi)有跨進(jìn)程的同步時(shí)鐘饶深,但每個(gè)進(jìn)程的本地時(shí)間仍以近似相同的速度流動(dòng)餐曹,其誤差與鎖的自動(dòng)釋放時(shí)間相比很小。這個(gè)假設(shè)與現(xiàn)實(shí)世界的計(jì)算機(jī)非常相似:每臺(tái)計(jì)算機(jī)都有一個(gè)本地時(shí)鐘敌厘,我們通程ê铮可以依靠不同的計(jì)算機(jī)有一個(gè)很小的時(shí)鐘漂移。
在這一點(diǎn)上,我們需要更好地說(shuō)明我們的互斥規(guī)則:只要持有鎖的客戶(hù)端將在鎖的有效期內(nèi)(如在步驟3中得到的)饱狂,減去一些時(shí)間(為了補(bǔ)償進(jìn)程間的時(shí)鐘漂移曹步,只需幾毫秒)終止其工作,就可以保證休讳。
關(guān)于需要約束時(shí)鐘漂移的類(lèi)似系統(tǒng)的更多信息讲婚,這篇論文是一個(gè)有趣的參考。租約: 分布式文件緩存一致性的高效容錯(cuò)機(jī)制 http://dl.acm.org/citation.cfm?id=74870俊柔。
失敗時(shí)重試
當(dāng)客戶(hù)端無(wú)法獲取鎖時(shí)筹麸,它應(yīng)該在隨機(jī)延遲后再次嘗試,以嘗試對(duì)試圖在同一時(shí)間為同一資源獲取鎖的多個(gè)客戶(hù)端進(jìn)行異步處理(這可能會(huì)導(dǎo)致大腦分裂的情況雏婶,沒(méi)有人獲勝)物赶。另外,客戶(hù)端試圖在大多數(shù)Redis實(shí)例中獲取鎖的速度越快留晚,出現(xiàn)大腦分裂狀況的窗口就越锌椴睢(需要重試),所以理想情況下倔丈,客戶(hù)端應(yīng)該嘗試使用復(fù)用技術(shù)同時(shí)向N個(gè)實(shí)例發(fā)送SET命令。
值得強(qiáng)調(diào)的是状蜗,對(duì)于未能獲得大部分鎖的客戶(hù)端來(lái)說(shuō)需五,盡快釋放(部分)獲得的鎖是非常重要的,這樣就不需要等待密鑰過(guò)期轧坎,以便再次獲得鎖(然而宏邮,如果發(fā)生網(wǎng)絡(luò)分區(qū),客戶(hù)端不再能夠與Redis實(shí)例進(jìn)行通信缸血,在等待密鑰過(guò)期時(shí)蜜氨,需要支付可用性罰款)。
釋放鎖
釋放鎖很簡(jiǎn)單捎泻,只需要在所有實(shí)例中釋放鎖飒炎,無(wú)論客戶(hù)是否認(rèn)為它能夠成功鎖定一個(gè)特定的實(shí)例。
安全論證
該算法是否安全笆豁?我們可以試著了解在不同的情況下會(huì)發(fā)生什么郎汪。
首先,我們假設(shè)一個(gè)客戶(hù)能夠在大多數(shù)實(shí)例中獲得鎖闯狱。所有的實(shí)例將包含一個(gè)具有相同生存時(shí)間的密鑰煞赢。然而,鑰匙的設(shè)置時(shí)間不同哄孤,所以鑰匙也會(huì)在不同的時(shí)間過(guò)期照筑。但是,如果第一個(gè)密鑰在最壞的情況下被設(shè)置在時(shí)間T1(我們?cè)诼?lián)系第一個(gè)服務(wù)器之前的采樣時(shí)間),而最后一個(gè)密鑰在最壞的情況下被設(shè)置在時(shí)間T2(我們從最后一個(gè)服務(wù)器獲得回復(fù)的時(shí)間)凝危,我們可以肯定波俄,集合中第一個(gè)過(guò)期的密鑰將至少存在MIN_VALIDITY=TTL-(T2-T1)-CLOCK_DRIFT。所有其他的鑰匙將在以后過(guò)期媒抠,所以我們確信鑰匙將同時(shí)設(shè)置至少這個(gè)時(shí)間弟断。
在大多數(shù)鑰匙被設(shè)置的時(shí)間里,另一個(gè)客戶(hù)端將無(wú)法獲得鎖趴生,因?yàn)槿绻鸑/2+1個(gè)鑰匙已經(jīng)存在阀趴,N/2+1個(gè)SET NX操作就不能成功。因此苍匆,如果一個(gè)鎖被獲取了刘急,就不可能在同一時(shí)間重新獲取它(違反了互斥屬性)。
然而我們也要確保多個(gè)試圖同時(shí)獲取鎖的客戶(hù)端不能同時(shí)成功浸踩。
如果一個(gè)客戶(hù)端使用接近或大于鎖的最大有效時(shí)間(基本上是我們用于SET的TTL)鎖定了大多數(shù)實(shí)例叔汁,它將認(rèn)為該鎖無(wú)效并將解鎖這些實(shí)例,所以我們只需要考慮一個(gè)客戶(hù)端能夠在小于有效時(shí)間的時(shí)間內(nèi)鎖定大多數(shù)實(shí)例的情況检碗。在這種情況下据块,對(duì)于上面已經(jīng)表達(dá)的論點(diǎn),對(duì)于MIN_VALIDITY來(lái)說(shuō)折剃,沒(méi)有客戶(hù)端應(yīng)該能夠重新獲得鎖另假。所以多個(gè)客戶(hù)端將能夠同時(shí)鎖定N/2+1個(gè)實(shí)例("時(shí)間 "是指步驟2的結(jié)束時(shí)間),只有當(dāng)鎖定大多數(shù)的時(shí)間大于TTL時(shí)間時(shí)怕犁,才能使鎖無(wú)效边篮。
你是否能夠提供一個(gè)正式的安全證明,指出現(xiàn)有的類(lèi)似算法奏甫,或者找到一個(gè)錯(cuò)誤戈轿?這將是非常感謝的。
有效性論據(jù)
系統(tǒng)的有效性是基于三個(gè)主要特征阵子。
- 自動(dòng)釋放鎖(因?yàn)殍€匙過(guò)期):最終鑰匙可以再次被鎖定思杯。
- 事實(shí)上,客戶(hù)端款筑,通常會(huì)在沒(méi)有獲得鎖的時(shí)候智蝠,或者在獲得了鎖而工作終止的時(shí)候,合作移除鎖奈梳,這使得我們很可能不需要等待鑰匙過(guò)期來(lái)重新獲得鎖杈湾。
- 事實(shí)上,當(dāng)客戶(hù)端需要重試一個(gè)鎖時(shí)攘须,它所等待的時(shí)間要比獲取大多數(shù)鎖所需的時(shí)間大得多漆撞,以概率地使資源爭(zhēng)奪期間的分腦條件不太可能發(fā)生。
然而,我們支付的可用性懲罰等于網(wǎng)絡(luò)分區(qū)的TTL時(shí)間浮驳,所以如果有連續(xù)的分區(qū)悍汛,我們可以無(wú)限期地支付這個(gè)懲罰。每當(dāng)一個(gè)客戶(hù)獲得一個(gè)鎖至会,并在能夠移除該鎖之前被分區(qū)時(shí)离咐,就會(huì)發(fā)生這種情況。
基本上奉件,如果有無(wú)限的連續(xù)網(wǎng)絡(luò)分區(qū)宵蛀,系統(tǒng)可能在無(wú)限長(zhǎng)的時(shí)間
性能、崩潰恢復(fù)和fsync
許多使用Redis作為鎖服務(wù)器的用戶(hù)需要高性能县貌,包括獲取和釋放鎖的延遲术陶,以及每秒可能進(jìn)行的獲取/釋放操作的數(shù)量。為了滿(mǎn)足這一要求煤痕,與N個(gè)Redis服務(wù)器對(duì)話(huà)以減少延遲的策略肯定是多路復(fù)用(或窮人的多路復(fù)用梧宫,即把套接字置于非阻塞模式,發(fā)送所有的命令摆碉,隨后讀取所有的命令塘匣,假設(shè)客戶(hù)端和每個(gè)實(shí)例之間的RTT相似)。
然而巷帝,如果我們想以崩潰恢復(fù)系統(tǒng)模型為目標(biāo)馆铁,還有另一個(gè)關(guān)于持久性的考慮要做。
基本上要看到這里的問(wèn)題锅睛,讓我們假設(shè)我們配置的Redis完全沒(méi)有持久性。一個(gè)客戶(hù)端在5個(gè)實(shí)例中的3個(gè)獲得了鎖历谍∠志埽客戶(hù)端能夠獲得鎖的其中一個(gè)實(shí)例被重新啟動(dòng),此時(shí)又有3個(gè)實(shí)例可以為同一資源加鎖望侈,另一個(gè)客戶(hù)端可以再次加鎖印蔬,違反了鎖的排他性的安全屬性。
如果我們啟用AOF持久性脱衙,情況會(huì)有很大的改善侥猬。例如,我們可以通過(guò)發(fā)送SHUTDOWN和重啟來(lái)升級(jí)服務(wù)器捐韩。因?yàn)镽edis的過(guò)期時(shí)間在語(yǔ)義上是這樣實(shí)現(xiàn)的:當(dāng)服務(wù)器關(guān)閉時(shí)退唠,實(shí)際上時(shí)間仍然在流逝,我們所有的要求都很好荤胁。然而瞧预,只要是干凈的關(guān)機(jī),一切都很好。那停電呢垢油?如果Redis被配置為默認(rèn)的每秒在磁盤(pán)上進(jìn)行fsync盆驹,那么在重新啟動(dòng)后,我們的密鑰有可能丟失滩愁。理論上躯喇,如果我們想在任何形式的實(shí)例重啟時(shí)保證鎖的安全,我們需要在持久性設(shè)置中啟用fsync=always硝枉。這反過(guò)來(lái)又會(huì)完全破壞性能廉丽,使之與傳統(tǒng)上用于安全實(shí)現(xiàn)分布式鎖的CP系統(tǒng)的水平相同。
然而檀咙,事情要比乍看之下要好得多雅倒。基本上弧可,只要當(dāng)一個(gè)實(shí)例在崩潰后重新啟動(dòng)時(shí)蔑匣,它不再參與任何當(dāng)前活動(dòng)的鎖,那么算法的安全性就會(huì)被保留下來(lái)棕诵,因此裁良,當(dāng)實(shí)例重新啟動(dòng)時(shí),當(dāng)前活動(dòng)的鎖集合都是由鎖的實(shí)例獲得的校套,而不是正在重新加入系統(tǒng)的那個(gè)价脾。
為了保證這一點(diǎn),我們只需要讓一個(gè)實(shí)例在崩潰后笛匙,至少比我們使用的最大TTL多一點(diǎn)的時(shí)間不可用侨把,也就是實(shí)例崩潰時(shí)存在的所有鎖的鑰匙變得無(wú)效并被自動(dòng)釋放所需的時(shí)間。
使用延遲重啟基本上可以實(shí)現(xiàn)安全妹孙,即使沒(méi)有任何類(lèi)型的Redis持久性可用秋柄,但請(qǐng)注意,這可能轉(zhuǎn)化為可用性懲罰蠢正。例如骇笔,如果大多數(shù)實(shí)例崩潰,系統(tǒng)將成為全球不可用的TTL(這里的全球意味著在這段時(shí)間內(nèi)沒(méi)有任何資源可以被鎖定)嚣崭。
讓算法更可靠笨触。延長(zhǎng)鎖的有效期
如果客戶(hù)端執(zhí)行的工作是由小步驟組成的,就有可能在默認(rèn)情況下使用較小的鎖有效期雹舀,并通過(guò)實(shí)施鎖擴(kuò)展機(jī)制來(lái)擴(kuò)展該算法芦劣。基本上说榆,客戶(hù)端持寄,如果在計(jì)算中間源梭,而鎖的有效性接近一個(gè)低值,可以通過(guò)向所有的實(shí)例發(fā)送一個(gè)Lua腳本來(lái)擴(kuò)展鎖稍味,如果鑰匙存在并且其值仍然是客戶(hù)端在獲得鎖時(shí)分配的隨機(jī)值废麻,則擴(kuò)展鎖。
客戶(hù)端只有在能夠?qū)㈡i擴(kuò)展到大多數(shù)實(shí)例模庐,并且在有效期內(nèi)(基本上使用的算法與獲取鎖時(shí)使用的算法非常相似)烛愧,才應(yīng)該考慮重新獲得鎖。
然而掂碱,這在技術(shù)上并沒(méi)有改變算法怜姿,所以應(yīng)該限制重新獲取鎖的最大次數(shù),否則就違反了有效性屬性之一疼燥。
想幫忙嗎沧卢?
如果你對(duì)分布式系統(tǒng)感興趣的話(huà),希望能得到你的意見(jiàn)/分析醉者。另外但狭,參考其他語(yǔ)言的實(shí)現(xiàn)也很好。
謝謝撬即。
對(duì)Redlock的分析
Martin Kleppmann在這里分析了Redlock立磁。我不同意這個(gè)分析,并在這里發(fā)表了我對(duì)他的分析的答復(fù)剥槐。