深度解析 redis 分布式鎖,那些你不知道的秘密舶替!

Martin Kleppmann 于 2016 年 2 月 8 日發(fā)布,原文

作為我的書研究的一部分杠园,我在 Redis 網(wǎng)站上遇到了一種名為Redlock的算法顾瞪。該算法聲稱在Redis之上實(shí)現(xiàn)了容錯分布式鎖(或者更確切地說,租約[1])返劲,并且該頁面要求來自分布式系統(tǒng)人員的反饋玲昧。該算法本能地在我的腦海中敲響了警鐘,所以我花了一些時(shí)間思考并寫下了這些筆記篮绿。

由于Redlock 已經(jīng)有 10 多個(gè)獨(dú)立的實(shí)現(xiàn)孵延,我們不知道誰已經(jīng)在依賴這個(gè)算法,我認(rèn)為值得公開分享我的筆記亲配。我不會深入探討 Redis 的其他方面尘应,其中一些已經(jīng)在其他地方受到批評

在詳細(xì)介紹 Redlock 之前吼虎,先說我非常喜歡 Redis犬钢,并且我過去在生產(chǎn)中成功使用過它。我認(rèn)為它非常適合您希望在服務(wù)器之間共享一些瞬態(tài)思灰、近似玷犹、快速變化的數(shù)據(jù)的情況,并且如果您偶爾出于某種原因丟失這些數(shù)據(jù)也沒什么大不了的洒疚。例如歹颓,一個(gè)很好的用例是維護(hù)每個(gè) IP 地址的請求計(jì)數(shù)器(為了限制訪問速率)和每個(gè)用戶 ID它使用的不同 IP 地址集(用于濫用檢測)。

然而油湖,Redis 已經(jīng)逐漸進(jìn)入數(shù)據(jù)管理領(lǐng)域巍扛,那里需要有更強(qiáng)的一致性和持久性——這讓我擔(dān)心,因?yàn)檫@不是 Redis 的設(shè)計(jì)目標(biāo)乏德〕芳椋可以說,分布式鎖是這些領(lǐng)域之一。讓我們更詳細(xì)地研究一下胧瓜。

你用那把鎖做什么矢棚?

加鎖的目的是確保多個(gè)節(jié)點(diǎn)在嘗試執(zhí)行相同工作時(shí),只有一個(gè)節(jié)點(diǎn)實(shí)際執(zhí)行此操作(至少一次只有一個(gè))贷痪。 這項(xiàng)工作可能是將一些數(shù)據(jù)寫入共享存儲系統(tǒng)幻妓、執(zhí)行一些計(jì)算蹦误、調(diào)用一些外部 API 等劫拢。概括而言,您可能需要在分布式應(yīng)用程序中使用鎖的原因有兩個(gè):為了效率或?yàn)榱苏_性 [2]强胰。為了區(qū)分這些情況舱沧,你可以問如果鎖失敗會發(fā)生什么:

效率:獲取鎖可以避免不必要地做兩次相同的工作(例如一些昂貴的計(jì)算)。如果加鎖失敗并且兩個(gè)節(jié)點(diǎn)最終完成相同的工作偶洋,結(jié)果是成本略有增加(您最終向 AWS 支付的費(fèi)用比其他情況多 5 美分)或帶來輕微的不便(例如熟吏,用戶最終兩次收到相同的電子郵件通知)。

正確性:使用鎖可以防止并發(fā)進(jìn)程相互干擾并破壞系統(tǒng)狀態(tài)玄窝。如果加鎖失敗導(dǎo)致兩個(gè)節(jié)點(diǎn)同時(shí)處理同一條數(shù)據(jù)牵寺,后果可能是文件損壞、數(shù)據(jù)丟失恩脂、永久性不一致帽氓、給患者服用的藥物劑量錯誤或其他一些嚴(yán)重問題。

以上兩者都是需要使用鎖的原因俩块,但您需要非常清楚您正在處理兩者中的哪一個(gè)黎休。

如果您僅出于效率目的使用鎖,則沒有必要承擔(dān) Redlock 的成本和復(fù)雜性玉凯,運(yùn)行 5 個(gè) Redis 服務(wù)器并檢查大多數(shù)以獲得您的鎖势腮。您最好只使用單個(gè) Redis 實(shí)例,也許可以異步復(fù)制到副本實(shí)例漫仆,以防主實(shí)例崩潰捎拯。

如果你使用單個(gè)Redis實(shí)例,當(dāng)然你的Redis節(jié)點(diǎn)突然斷電盲厌,或者出現(xiàn)其他問題署照,你的鎖也會出現(xiàn)一些問題。但如果你只是將鎖用作效率優(yōu)化狸眼,并且崩潰不會經(jīng)常發(fā)生藤树,那沒什么大不了的。這種“沒什么大不了”的場景正是 Redis的用武之地拓萌。至少岁钓,如果您依賴單個(gè) Redis 實(shí)例,那么查看系統(tǒng)的每個(gè)人都清楚鎖定是近似的,并且僅用于非關(guān)鍵目的屡限。

另一方面品嚣,具有 5 個(gè)副本和多數(shù)投票的 Redlock 算法乍一看似乎適用于對鎖的正確性有嚴(yán)格要求的情況。我將在以下各節(jié)中爭辯說它不適合該目的钧大。對于本文的其余部分翰撑,我們將假設(shè)您的鎖對于正確性很重要,如果兩個(gè)不同的節(jié)點(diǎn)同時(shí)認(rèn)為它們持有相同的鎖啊央,這將是一個(gè)嚴(yán)重的錯誤眶诈。

用鎖保護(hù)資源

讓我們暫時(shí)先把 Redlock 的細(xì)節(jié)放在一邊,然后討論一下分布式鎖的一般的使用方式(獨(dú)立于所使用的特定鎖算法)瓜饥。 重要的是要記住逝撬,分布式系統(tǒng)中的鎖不像多線程應(yīng)用程序中的互斥鎖。 這是一個(gè)更復(fù)雜的設(shè)計(jì)乓土,由于不同節(jié)點(diǎn)和網(wǎng)絡(luò)都可能以各種方式獨(dú)立失敗宪潮。

例如,假設(shè)您有一個(gè)應(yīng)用程序趣苏,其中客戶端需要更新共享存儲(例如 HDFS 或 S3)中的文件狡相。 客戶端首先獲取鎖,然后讀取文件食磕,進(jìn)行一些更改尽棕,將修改后的文件寫回,最后釋放鎖芬为。 該鎖可防止兩個(gè)客戶端同時(shí)執(zhí)行此讀取-修改-寫入循環(huán)萄金,這會導(dǎo)致更新丟失。 代碼可能如下所示:

不幸的是媚朦,即使你有完美的鎖服務(wù)氧敢,上面的代碼也會被破壞。 下圖顯示了數(shù)據(jù)如何被損壞:

在這個(gè)例子中询张,獲取鎖的客戶端在持有鎖后暫停了很長一段時(shí)間——例如因?yàn)槔占鳎℅C)的啟動孙乖。鎖有一個(gè)超時(shí)(即它是一個(gè)租約),這總是一個(gè)好主意(否則崩潰的客戶端最終可能會永遠(yuǎn)持有鎖并且永遠(yuǎn)不會釋放它)份氧。但是唯袄,如果 GC 暫停持續(xù)時(shí)間超過租用到期時(shí)間,并且客戶端沒有意識到自己持有的鎖已經(jīng)過期蜗帜,它可能會繼續(xù)進(jìn)行一些不安全的更改恋拷。

這個(gè)錯誤就曾經(jīng)發(fā)生過:HBase 曾經(jīng)有這個(gè)問題 [3,4]。通常情況下厅缺,GC 暫停時(shí)間很短蔬顾,但“stop-the-world”的GC暫停有時(shí)會持續(xù)幾分鐘 [5]——當(dāng)然足以讓租約到期宴偿。即使是所謂的“并發(fā)”垃圾收集器,如 HotSpot JVM 的 CMS诀豁,也不能完全與應(yīng)用程序代碼并行運(yùn)行——即使它們有時(shí)需要"stop-the-world" [6]窄刘。

您無法通過在寫回存儲之前插入對鎖定到期的檢查來解決此問題。請記住舷胜,GC 可以在任何時(shí)間暫停正在運(yùn)行的線程娩践,包括對您來說最不方便的時(shí)間點(diǎn)(在最后一次檢查和寫入操作之間)。

如果您因?yàn)樽约菏褂玫木幊陶Z言運(yùn)行時(shí)沒有長時(shí)間的 GC 暫停而感到自鳴得意烹骨,那么您的進(jìn)程可能會因許多其他原因而暫停翻伺。比如也許您的進(jìn)程試圖讀取尚未加載到內(nèi)存中的地址,因此它會出現(xiàn)缺頁錯誤并暫停展氓,直到從磁盤加載該頁面穆趴。也許您的磁盤實(shí)際上是 EBS,因此讀取一個(gè)變量在不知不覺中變成了 Amazon 擁塞網(wǎng)絡(luò)上的同步網(wǎng)絡(luò)請求遇汞。也許還有許多其他進(jìn)程在爭奪 CPU,而您在調(diào)度程序樹中遇到了一個(gè)黑色節(jié)點(diǎn)簿废。也許有人不小心向進(jìn)程發(fā)送了 SIGSTOP等空入,都會使進(jìn)程暫停。

如果您仍然不相信進(jìn)程暫停族檬,那么請考慮文件寫入請求在到達(dá)存儲服務(wù)器之前可能會因?yàn)榫W(wǎng)絡(luò)堵塞而延遲歪赢。以太網(wǎng)和 IP 等數(shù)據(jù)包網(wǎng)絡(luò)可能會使數(shù)據(jù)包出現(xiàn)任意延遲,它們確實(shí)如此 [7]:在 GitHub 的一個(gè)著名事件中单料,數(shù)據(jù)包在網(wǎng)絡(luò)中延遲了大約 90 秒 [8]埋凯。這意味著一個(gè)應(yīng)用進(jìn)程可能會發(fā)送一個(gè)寫請求,當(dāng)租約已經(jīng)到期時(shí)扫尖,它可能會在一分鐘后才到達(dá)存儲服務(wù)器白对。

即使在管理良好的網(wǎng)絡(luò)中,這種事情也可能發(fā)生换怖。你根本無法對時(shí)間做出任何假設(shè)甩恼,所以無論你使用哪種鎖服務(wù),上面的代碼都是不安全的沉颂。

使用防護(hù)使鎖安全

修復(fù)上面的問題其實(shí)非常簡單:對存儲服務(wù)的每個(gè)寫請求中都帶一個(gè)防護(hù)令牌条摸。在這種情況下,防護(hù)令牌只需要是一個(gè)數(shù)字铸屉,每次客戶端獲取鎖時(shí)它都會遞增(例如钉蒲,由鎖服務(wù)遞增)。如下圖所示:

客戶端1獲得租約和值為33的令牌彻坛,但隨后進(jìn)入長時(shí)間暫停顷啼,租約到期帆赢。客戶端 2 獲取租約线梗,得到值為34 的令牌(數(shù)字總是遞增)椰于,然后將內(nèi)容和值為34的令牌都寫入到存儲服務(wù)。稍后仪搔,客戶端1恢復(fù)正常后瘾婿,將寫入請求:內(nèi)容和值為33的令牌 發(fā)送到存儲服務(wù)。但是烤咧,存儲服務(wù)器記住它已經(jīng)處理了具有更高令牌號 (34) 的寫入偏陪,因此它拒絕帶有令牌 33 的請求。

請注意煮嫌,這需要存儲服務(wù)器采取主動角色檢查令牌笛谦,并拒絕令牌倒退的任何寫入。但這并不是特別難昌阿,一旦你知道了訣竅饥脑。并且如果鎖服務(wù)生成嚴(yán)格單調(diào)遞增的令牌,這使得鎖是安全的懦冰。例如灶轰,如果您使用 ZooKeeper 作為鎖定服務(wù),您可以使用 zxid 或 znode 版本號作為防護(hù)令牌刷钢,并且您處于良好狀態(tài) [3]笋颤。

然而,這將我們引向了 Redlock 的第一個(gè)大問題:它沒有任何用于生成隔離令牌的工具内地。該算法不會產(chǎn)生任何保證--即每次客戶端獲取鎖時(shí)都會遞增的數(shù)字伴澄。這意味著即使算法在其他方面是完美的,使用它也不安全阱缓,因?yàn)樵谝粋€(gè)客戶端暫头橇瑁或其數(shù)據(jù)包延遲的情況下,您無法防止客戶端之間的競爭條件茬祷。

對我來說清焕,如何更改 Redlock 算法以開始生成防護(hù)令牌并不明顯。它使用的唯一隨機(jī)值不提供所需的單調(diào)性祭犯。僅僅在一個(gè) Redis 節(jié)點(diǎn)上保留一個(gè)計(jì)數(shù)器是不夠的秸妥,因?yàn)樵摴?jié)點(diǎn)可能會失敗。在多個(gè)節(jié)點(diǎn)上保留計(jì)數(shù)器意味著它們的數(shù)據(jù)會出現(xiàn)不同步或同步不及時(shí)沃粗。您可能需要一個(gè)共識算法來生成圍欄令牌粥惧。 (如果只是增加一個(gè)計(jì)數(shù)器是簡單的。)

用時(shí)間解決共識

在想使用鎖保證正確性的情況下不應(yīng)該使用Redlock最盅,因?yàn)镽edlock無法生成 fencing 令牌突雪。但還有一些更進(jìn)一步的問題值得討論起惕。

在學(xué)術(shù)文獻(xiàn)中,這種算法最實(shí)用的系統(tǒng)模型是帶有不可靠故障檢測器的異步模型 [9]咏删。簡單來說惹想,這意味著算法不對時(shí)間做任何假設(shè):進(jìn)程可能會暫停任意長度的時(shí)間,數(shù)據(jù)包可能會在網(wǎng)絡(luò)中任意延遲督函,時(shí)鐘可能會任意錯誤——盡管如此嘀粱,算法都會做正確的事物。鑒于我們上面討論的內(nèi)容辰狡,這些都是非常合理的假設(shè)锋叨。

算法使用時(shí)鐘的唯一目的是產(chǎn)生超時(shí),以避免在節(jié)點(diǎn)關(guān)閉時(shí)永遠(yuǎn)等待宛篇。但是超時(shí)不一定準(zhǔn)確:僅僅因?yàn)檎埱蟪瑫r(shí)娃磺,并不意味著另一個(gè)節(jié)點(diǎn)已關(guān)閉 – 也可能是網(wǎng)絡(luò)中存在很大延遲,或者您的本地時(shí)鐘是錯的叫倍。當(dāng)用作故障檢測器時(shí)偷卧,超時(shí)只是猜測出了問題。 (如果可以的話段标,分布式算法將完全沒有時(shí)鐘涯冠,但這樣就不可能達(dá)成共識 [10]。獲取鎖就像一個(gè)比較和設(shè)置操作逼庞,需要達(dá)成共識 [11]。)

請注意瞻赶,Redis 使用gettimeofday赛糟,而不是單調(diào)時(shí)鐘,以確定密鑰的到期時(shí)間砸逊。 gettimeofday 的手冊頁明確指出它返回的時(shí)間會受到系統(tǒng)時(shí)間不連續(xù)跳躍的影響——也就是說璧南,它可能會突然向前跳躍幾分鐘,甚至?xí)r間跳躍(例如师逸,如果時(shí)鐘被NTP步進(jìn)司倚,因?yàn)樗c NTP 服務(wù)器差別太大,或者如果時(shí)鐘由管理員手動調(diào)整)篓像。因此动知,如果系統(tǒng)時(shí)鐘正在做一些奇怪的事情,很容易發(fā)生 Redis 中某個(gè)鍵的到期比預(yù)期快得多或慢得多的情況员辩。

對于異步模型中的算法盒粮,這不是一個(gè)大問題:這些算法通常會在不基于時(shí)間做出假設(shè)[12]的前提下保證它們的安全屬性始終不變。只有活性屬性取決于超時(shí)或其他一些故障檢測器奠滑。通俗地說丹皱,這意味著即使計(jì)時(shí)在系統(tǒng)中到處都是(進(jìn)程暫停妒穴,網(wǎng)絡(luò)延遲,時(shí)鐘向前和向后跳躍)摊崭,導(dǎo)致算法的性能可能會下降讼油,但算法永遠(yuǎn)不會做出錯誤的決定。

然而呢簸,Redlock不是這樣的矮台。它的安全性取決于很多時(shí)間假設(shè):

它假設(shè)所有 Redis 節(jié)點(diǎn)在過期前都持有大約合適的時(shí)間長度

網(wǎng)絡(luò)延遲比過期時(shí)間短得多

進(jìn)程暫停時(shí)間比過期時(shí)間短得多

基于時(shí)間假設(shè)的Redlock不可靠

讓我們看一些例子來證明 Redlock 對時(shí)間假設(shè)的依賴。假設(shè)系統(tǒng)有五個(gè) Redis 節(jié)點(diǎn)(A阔墩、B嘿架、C、D 啸箫、 E)和兩個(gè)客戶端(1 和 2)耸彪。如果其中一個(gè) Redis 節(jié)點(diǎn)上的時(shí)鐘向前跳躍會發(fā)生什么?

客戶端 1 獲取節(jié)點(diǎn) A忘苛、B碱蒙、C 上的鎖偿警。由于網(wǎng)絡(luò)問題,無法訪問 D 和 E。

節(jié)點(diǎn) C 上的時(shí)鐘向前跳躍鳍贾,導(dǎo)致鎖到期。

客戶端 2 獲取節(jié)點(diǎn) C评汰、D读拆、E 上的鎖。由于網(wǎng)絡(luò)問題纸镊,無法訪問 A 和 B倍阐。

客戶端 1 和 2 現(xiàn)在都相信他們持有鎖。

如果 C 在將鎖定持久化到磁盤之前崩潰并立即重新啟動逗威,則可能會發(fā)生類似的問題峰搪。出于這個(gè)原因,Redlock 文檔建議至少將崩潰節(jié)點(diǎn)的重啟延遲到鎖的最長存活時(shí)間凯旭。但是這種重新啟動延遲再次依賴于合理準(zhǔn)確的時(shí)間測量概耻,但在發(fā)生時(shí)鐘跳躍時(shí)也會導(dǎo)致失敗。

可能您認(rèn)為發(fā)生時(shí)鐘跳躍不現(xiàn)實(shí)罐呼,因?yàn)槟鷮φ_配置 NTP 以調(diào)整時(shí)鐘非常有信心鞠柄。在這種情況下,讓我們看一個(gè)進(jìn)程暫停如何導(dǎo)致算法失敗的示例:

客戶端 1 請求在節(jié)點(diǎn) A弄贿、B春锋、C、D差凹、E 上鎖定期奔。

當(dāng)對客戶端 1 的響應(yīng)在進(jìn)行中時(shí)侧馅,客戶端 1 去進(jìn)入 stop-the-world GC。

所有 Redis 節(jié)點(diǎn)上的鎖都會過期呐萌。

客戶端 2 在節(jié)點(diǎn) A馁痴、B、C肺孤、D罗晕、E 上獲取鎖。

客戶端 1 完成 GC赠堵,并收到來自 Redis 節(jié)點(diǎn)的響應(yīng)小渊,表明它已成功獲取鎖(它們在進(jìn)程暫停時(shí)保存在客戶端 1 的內(nèi)核網(wǎng)絡(luò)緩沖區(qū)中) )。

客戶端 1 和 2 現(xiàn)在都相信他們持有鎖茫叭。

請注意酬屉,即使 Redis 是用 C 編寫的,因此沒有 GC揍愁,但這對我們沒有幫助:任何客戶端可能遇到GC暫停的系統(tǒng)都有這個(gè)問題呐萨。您只能通過在客戶端 2 獲取鎖后阻止客戶端 1 在鎖下執(zhí)行任何操作來確保安全,例如使用上面的防護(hù)方法莽囤。

較長的網(wǎng)絡(luò)延遲會產(chǎn)生與進(jìn)程暫停相同的效果谬擦。這可能取決于您的 TCP 用戶超時(shí)——如果您使超時(shí)明顯短于 Redis TTL,則可能會忽略延遲的網(wǎng)絡(luò)數(shù)據(jù)包朽缎,但我們必須詳細(xì)查看 TCP 實(shí)現(xiàn)才能確定惨远。此外,隨著超時(shí)话肖,我們再次回到時(shí)間測量的準(zhǔn)確性锨络!

Redlock的同步假設(shè)

這些例子表明,Redlock 只有在你假設(shè)一個(gè)同步系統(tǒng)模型時(shí)才能正確工作——也就是說狼牺,一個(gè)系統(tǒng)具有以下屬性:

有界網(wǎng)絡(luò)延遲(你可以保證數(shù)據(jù)包總是在某個(gè)最大延遲時(shí)刻內(nèi)到達(dá))

有界進(jìn)程暫停(換句話說,hard real-time constraints礼患,您通常只能在汽車安全氣囊系統(tǒng)等中找到)

有限的時(shí)鐘誤差(難以避免從壞的NTP服務(wù)器獲取時(shí)間)

請注意是钥,同步模型并不意味著完全同步的時(shí)鐘:這意味著您假設(shè)網(wǎng)絡(luò)延遲、暫停和時(shí)鐘漂移有一個(gè)已知的缅叠、固定的上限 [12]悄泥。 Redlock 假設(shè)延遲、暫停和漂移相對于鎖的生存時(shí)間來說都很蟹袅弧弹囚; 如果時(shí)序問題變得與生存時(shí)間一樣大,算法就會失敗领曼。

在行為合理的數(shù)據(jù)中心環(huán)境中鸥鹉,大部分時(shí)間都會滿足時(shí)序假設(shè)——這被稱為部分同步系統(tǒng) [12]蛮穿。但這足夠了嗎?一旦這些時(shí)間假設(shè)被打破毁渗,Redlock 可能會違反其安全屬性践磅,例如在另一個(gè)客戶端到期之前向一個(gè)客戶端授予租約。如果你依賴你的鎖來保證正確性灸异,“大部分時(shí)間”是不夠的——你需要它總是正確的府适。

有大量證據(jù)表明,為大多數(shù)實(shí)際系統(tǒng)環(huán)境假設(shè)同步系統(tǒng)模型是不安全的 [7,8]肺樟。不斷提醒自己 GitHub 事件的[90 秒數(shù)據(jù)包延遲](90-second packet delay)檐春。 Redlock 不太可能在Jepsen測試中幸存下來。

另一方面么伯,為部分同步系統(tǒng)模型(或帶有故障檢測器的異步模型)設(shè)計(jì)的共識算法是時(shí)候上場了疟暖。 Raft、Viewstamped Replication蹦狂、Zab 和 Paxos 都屬于這一類誓篱。這樣的算法必須放棄所有時(shí)序假設(shè)。這很難:假設(shè)網(wǎng)絡(luò)凯楔、進(jìn)程和時(shí)鐘比實(shí)際情況更可靠是很誘人的窜骄。但是在分布式系統(tǒng)的混亂現(xiàn)實(shí)中,你必須非常小心你的假設(shè)摆屯。

結(jié)論

我認(rèn)為 Redlock 算法是一個(gè)糟糕的選擇:對于效率優(yōu)化來說實(shí)現(xiàn)太復(fù)雜邻遏、成本昂貴的,對于想保證正確性的場景來說它又不夠安全虐骑。

特別是准验,該算法對時(shí)序和系統(tǒng)時(shí)鐘做出了危險(xiǎn)的假設(shè)(基本上假設(shè)同步系統(tǒng)具有有限的網(wǎng)絡(luò)延遲和有限的操作執(zhí)行時(shí)間),如果不滿足這些假設(shè)廷没,則會違反安全屬性糊饱。此外,它缺乏用于生成隔離令牌的設(shè)施(保護(hù)系統(tǒng)免受網(wǎng)絡(luò)長時(shí)間延遲或暫停進(jìn)程的影響)颠黎。

如果使用鎖是出于效率優(yōu)化的目的且可以容忍一定程度的不正確性另锋,我建議堅(jiān)持使用簡單的 Redis單節(jié)點(diǎn)鎖定算法(條件設(shè)置如果不存在以獲得鎖, atomic delete-if-value-matches 以釋放鎖)狭归,并在您的代碼中非常清楚地記錄鎖只是近似值夭坪,有時(shí)可能會失敗。不要費(fèi)心設(shè)置五個(gè) Redis 節(jié)點(diǎn)的集群过椎。

另一方面室梅,如果您需要鎖定以確保正確性,請不要使用 Redlock。相反亡鼠,請使用適當(dāng)?shù)墓沧R系統(tǒng)赏殃,例如 ZooKeeper,可能通過實(shí)現(xiàn)鎖定的 Curator recipes之一拆宛。 (至少嗓奢,使用具有合理事務(wù)保證的數(shù)據(jù)庫。)并且請?jiān)阪i定下的所有資源訪問中強(qiáng)制使用防護(hù)令牌浑厚。

正如我在開頭所說的股耽,如果正確使用Redis,它是一個(gè)很好的工具钳幅。以上都不會降低 Redis 對其預(yù)期用途的實(shí)用性物蝙。 Salvatore 多年來一直致力于該項(xiàng)目,其成功當(dāng)之無愧敢艰。但是每個(gè)工具都有局限性诬乞,了解它們并相應(yīng)地進(jìn)行計(jì)劃很重要。

如果您想了解更多信息钠导,我在本書的第8章和第9章中更詳細(xì)地解釋了這個(gè)主題震嫉,現(xiàn)在可以從 O'Reilly 獲得早期版本。 (上圖摘自我的書牡属。)為了學(xué)習(xí)如何使用 ZooKeeper票堵,我推薦Junqueira和Reed的書 [3]。為了更好地介紹分布式系統(tǒng)理論逮栅,我推薦Cachin悴势、Guerraoui 和 Rodrigues的教科書 [13]。

感謝 Kyle Kingsbury, Camille Fournier, Flavio Junqueira, 和 Salvatore Sanfilippo 審閱本文的草稿措伐。當(dāng)然特纤,任何錯誤都是我的。

2016 年 2 月 9 日更新:Redlock 的原作者 Salvatore本文進(jìn)行了反駁(另見HN討論))侥加。他提出了一些很好的觀點(diǎn)捧存,但我堅(jiān)持我的結(jié)論。如果我有時(shí)間担败,我可能會在后續(xù)文章中詳細(xì)說明矗蕊,但請形成您自己的意見——并請參閱下面的參考資料,其中許多已經(jīng)接受了嚴(yán)格的學(xué)術(shù)同行評審(與我們的任何一篇博文不同)氢架。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市朋魔,隨后出現(xiàn)的幾起案子岖研,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孙援,死亡現(xiàn)場離奇詭異害淤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)拓售,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門窥摄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人础淤,你說我怎么就攤上這事崭放。” “怎么了鸽凶?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵币砂,是天一觀的道長。 經(jīng)常有香客問我玻侥,道長决摧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任凑兰,我火速辦了婚禮掌桩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘姑食。我一直安慰自己波岛,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布矢门。 她就那樣靜靜地躺著盆色,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祟剔。 梳的紋絲不亂的頭發(fā)上隔躲,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機(jī)與錄音物延,去河邊找鬼宣旱。 笑死,一個(gè)胖子當(dāng)著我的面吹牛叛薯,可吹牛的內(nèi)容都是我干的浑吟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼耗溜,長吁一口氣:“原來是場噩夢啊……” “哼组力!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抖拴,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤燎字,失蹤者是張志新(化名)和其女友劉穎腥椒,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體候衍,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笼蛛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛉鹿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滨砍。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖妖异,靈堂內(nèi)的尸體忽然破棺而出惋戏,到底是詐尸還是另有隱情,我是刑警寧澤随闺,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布日川,位于F島的核電站,受9級特大地震影響矩乐,放射性物質(zhì)發(fā)生泄漏龄句。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一散罕、第九天 我趴在偏房一處隱蔽的房頂上張望分歇。 院中可真熱鬧,春花似錦欧漱、人聲如沸职抡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽缚甩。三九已至,卻和暖如春窑邦,著一層夾襖步出監(jiān)牢的瞬間擅威,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工冈钦, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留郊丛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓瞧筛,卻偏偏與公主長得像厉熟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子较幌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容