最近在做MIT6.824的幾個(gè)實(shí)驗(yàn)猜惋,真心覺(jué)得每一個(gè)做分布式相關(guān)開(kāi)發(fā)的程序員都應(yīng)該去刷一遍(裂墻推薦)猿妈,肯定能夠提高自己的技術(shù)認(rèn)知水平精钮,同時(shí)也非常感謝MIT能夠把這么好的資源分享出來(lái)袍啡。
其中第二個(gè)實(shí)驗(yàn)们衙,就是要基于raft算法钾怔,實(shí)現(xiàn)一個(gè)分布式一致性系統(tǒng)。但今天先不說(shuō)raft算法蒙挑,而是先討論下什么是分布式一致性問(wèn)題宗侦,以及為什么它會(huì)難!忆蚀!下一章再說(shuō)raft是如何設(shè)計(jì)從而解決了分布式共識(shí)這一難題矾利。
什么是分布式一致性問(wèn)題
首先,什么是分布式系統(tǒng)一致性問(wèn)題馋袜?分布式系統(tǒng)這個(gè)詞應(yīng)該不用多解釋男旗,簡(jiǎn)單地說(shuō)就是由多個(gè)節(jié)點(diǎn)(一個(gè)節(jié)點(diǎn)即一臺(tái)物理機(jī)器或一個(gè)進(jìn)程),異步得通過(guò)網(wǎng)絡(luò)通訊而組成的系統(tǒng)欣鳖。
而一致性(Consistency)察皇,這個(gè)詞在不同的場(chǎng)景下有不同的含義,比方說(shuō)大家比較熟的應(yīng)該是在關(guān)系型數(shù)據(jù)庫(kù)中事務(wù)的一致性观堂。但在分布式系統(tǒng)中让网,一致性的基本含義是對(duì)進(jìn)行進(jìn)行一個(gè)或多個(gè)操作指令之后,系統(tǒng)內(nèi)的其他成員對(duì)這些操作指令的結(jié)果能夠達(dá)成共識(shí)师痕,也就是對(duì)結(jié)果的看法是一致的溃睹。
舉個(gè)例子,比方說(shuō)有多個(gè)客戶端胰坟,這些客戶端出于某種原因因篇,都要對(duì)分布式系統(tǒng)中的變量v賦值,客戶端A發(fā)起一個(gè)賦值請(qǐng)求修改v=a笔横,客戶端B也發(fā)起一個(gè)請(qǐng)求修改v=b竞滓,等等等。但最終在某一個(gè)時(shí)刻布式系統(tǒng)內(nèi)都能夠?qū)的值產(chǎn)生一個(gè)共識(shí)吹缔,比如最終大家都知道v=a商佑。而不會(huì)說(shuō)系統(tǒng)內(nèi)不同節(jié)點(diǎn)對(duì)這個(gè)值有不同的看法。
要做到這一點(diǎn)很難嗎厢塘?是的茶没,很難肌幽。
注:一致性這個(gè)詞其實(shí)包含挺廣的,但這里特質(zhì)共識(shí)這個(gè)意思抓半,所以有時(shí)候也會(huì)用共識(shí)的說(shuō)法喂急,知道是一個(gè)意思就行了。
為什么分布式一致性問(wèn)題很難
明白了什么是分布式一致性問(wèn)題之后笛求,我們?cè)賮?lái)討論為什么分布式一致性會(huì)很難廊移。
如果是在單機(jī)環(huán)境下,實(shí)現(xiàn)一致性是很容易做到的探入,基本上我們開(kāi)發(fā)的程序都能夠做到狡孔。但在分布式環(huán)境下,則難度放大了無(wú)數(shù)倍新症。因?yàn)樵诜植际江h(huán)境下節(jié)點(diǎn)間的狀態(tài)是通過(guò)網(wǎng)絡(luò)通信進(jìn)行傳輸?shù)牟绞希W(wǎng)絡(luò)通信是不可靠的,無(wú)序的徒爹,注意這里的不可靠不是說(shuō)tcp或udp的那個(gè)可靠,而實(shí)無(wú)法通過(guò)網(wǎng)絡(luò)通信準(zhǔn)確判斷其他節(jié)點(diǎn)的狀態(tài)芋类。
比如A向B發(fā)送了一個(gè)請(qǐng)求隆嗅,B沒(méi)有回應(yīng)。這個(gè)時(shí)候你沒(méi)辦法判斷B是忙于處理其他任務(wù)而無(wú)法向A回復(fù)侯繁,還是因?yàn)锽就真的掛掉了胖喳。
順便說(shuō)一點(diǎn),分布式一致的問(wèn)題往往還具有一定的欺騙性贮竟。
它具有一定欺騙性的原因在于分布式一致性的問(wèn)題直觀感受上往往比較簡(jiǎn)單丽焊,比如上面的A向B發(fā)送請(qǐng)求的問(wèn)題,我們無(wú)論選擇直接認(rèn)為B掛掉咕别,或者選擇讓A不斷進(jìn)行重試技健,看上去似乎都能解決這個(gè)問(wèn)題。但隨著而來(lái)的又會(huì)有新問(wèn)題惰拱,比如A選擇認(rèn)為B掛掉而進(jìn)行失敗處理雌贱,那么系統(tǒng)繼續(xù)無(wú)礙運(yùn)行。但如果B只是因?yàn)橄到y(tǒng)任務(wù)繁忙偿短,過(guò)一會(huì)恢復(fù)作業(yè)欣孤,A就因?yàn)樽陨淼倪x擇破壞了數(shù)據(jù)的一致性,因?yàn)樵贐斷線期間系統(tǒng)就不一致了昔逗。這就又出現(xiàn)了新的問(wèn)題降传。
總結(jié)起來(lái),就是看似簡(jiǎn)單的問(wèn)題勾怒,引入簡(jiǎn)單的解婆排,往往又會(huì)出現(xiàn)新的問(wèn)題款票。而后又繼續(xù)在此基礎(chǔ)上“打補(bǔ)丁”,而后又會(huì)出現(xiàn)新的問(wèn)題泽论,不斷循環(huán)往復(fù)艾少,一個(gè)簡(jiǎn)單的問(wèn)題不斷疊加,就變成了超級(jí)復(fù)雜棘手的問(wèn)題翼悴。就像筑堤堵水缚够,水不斷漲,堤壩不斷堆砌鹦赎,最終到了一個(gè)誰(shuí)也沒(méi)法解決的境地谍椅。
說(shuō)回剛剛的話題,按照剛剛的例子古话,其實(shí)可以引出另一個(gè)問(wèn)題雏吭,那就是活性(liveness)和安全性(satefy)的取舍。
活性(liveness)與安全性(satefy)
活性與安全性陪踩,這個(gè)要怎么理解呢果覆?
剛剛說(shuō)到,當(dāng)A向B發(fā)送請(qǐng)求茬贵,B沒(méi)有及時(shí)回應(yīng)钉汗。但這個(gè)時(shí)候,A是無(wú)法準(zhǔn)確知道B真正的狀態(tài)的(忙于其他任務(wù)還是真的掛掉了)傻谁,也就是說(shuō)我們是無(wú)法做到完全正確的錯(cuò)誤檢測(cè)孝治。
這種時(shí)候按照上面的說(shuō)法,有兩種選擇审磁,
- 任務(wù)B依舊或者谈飒,無(wú)限重試,不斷等待态蒂。
- 直接認(rèn)為B掛掉了杭措,進(jìn)行錯(cuò)誤處理。
選擇1吃媒,破壞了系統(tǒng)的活性瓤介,因?yàn)樵谥卦嚨臅r(shí)間內(nèi),系統(tǒng)是無(wú)法對(duì)外提供服務(wù)的赘那,也就是短暫得失活了刑桑。
選2呢又破壞了安全性,因?yàn)槿绻鸅其實(shí)沒(méi)有掛掉募舟,而這時(shí)候重新啟動(dòng)一個(gè)節(jié)點(diǎn)負(fù)責(zé)原本B的工作祠斧,那么此時(shí)系統(tǒng)中就會(huì)有舊的B節(jié)點(diǎn),和新的B節(jié)點(diǎn)拱礁。此時(shí)舊的節(jié)點(diǎn)就稱之為僵尸節(jié)點(diǎn)(Zombie)琢锋。而如果在主從分布的系統(tǒng)辕漂,也就是一個(gè)leader多個(gè)follower的系統(tǒng)中,如果B剛好是leader吴超,那么這種情況也被稱之為腦裂钉嘹。
可以發(fā)現(xiàn),liveness和響應(yīng)速度有關(guān)鲸阻,而satefy又和系統(tǒng)的可用性相關(guān)跋涣,并且這兩者是不可兼得的。
關(guān)于這個(gè)問(wèn)題鸟悴,上世紀(jì)Lynch發(fā)表的一篇論文《Impossibility of Distributed Consensus with One Faulty Process》陈辱,基本上已經(jīng)闡述了這個(gè)定理,也就是FLP impossibility细诸。
FLP impossibility
FLP impossibility說(shuō)明了這樣一件事沛贪,在分布式或者說(shuō)異步環(huán)境下,即便只有一個(gè)進(jìn)程(節(jié)點(diǎn))失敗震贵,剩余的非失敗的進(jìn)程不可能達(dá)成一致性利赋。
這個(gè)是分布式領(lǐng)域中的定理,簡(jiǎn)稱就是FLP impossibility屏歹。
當(dāng)然所有的定理似乎都不是那么好理解隐砸,F(xiàn)LP impossibility也是一樣,光是結(jié)論聽(tīng)起來(lái)就非常拗口蝙眶。證明起來(lái)那就更加抽象,甚至在論文中也沒(méi)有通過(guò)例子來(lái)論證褪那。因?yàn)槿绻ㄟ^(guò)實(shí)例來(lái)論證幽纷,那么首先就得要先設(shè)計(jì)N多的分布式算法,然后再逐一證明這些算法是FLP impossibility博敬。
其實(shí)通俗些的理解友浸,那就是說(shuō)分布式(異步)環(huán)境下,liveness和satefy是魚與熊掌不可兼得偏窝。不可能做到100%的liveness同時(shí)又兼顧到satefy收恢。想要100%的satefy,那么liveness又保證不了祭往,這里面又好像有CAP的影子伦意,不得不說(shuō)道路都是相通的。
話說(shuō)回來(lái)硼补,既然FLP impossibility已經(jīng)說(shuō)死了驮肉,異步環(huán)境下,即便只有一個(gè)進(jìn)程(節(jié)點(diǎn))失敗已骇,剩余的非失敗的進(jìn)程不可能達(dá)成一致性离钝,那么paxos和raft這些算法又是如何做到分布式異步環(huán)境下一致的呢票编?
柳暗花明
其實(shí)FLP impossibility已經(jīng)為我們指明方向了。既然無(wú)法完全兼得卵渴,那自然要放松某方面的限制慧域,satefy是不能放松的,那自然只能從liveness上下手了浪读。
具體做法上昔榴,那就是給分布式系統(tǒng)加上一個(gè)時(shí)間限制,其實(shí)在前面介紹liveness和satefy的時(shí)候瑟啃,應(yīng)該就有人能想到了论泛。既然不能一直等待也不能直接任務(wù)遠(yuǎn)端節(jié)點(diǎn)掛掉,那么折衷一下蛹屿,在某個(gè)時(shí)間內(nèi)不斷重連屁奏,超過(guò)這個(gè)時(shí)間,則認(rèn)為遠(yuǎn)端節(jié)點(diǎn)是掛掉就可以了错负。
而事實(shí)上也正是如此坟瓢,如果你對(duì)zookeeper熟悉,那應(yīng)該知道zookeeper在選舉leader的時(shí)候是不提供服務(wù)的犹撒,這就是它喪失部分liveness的一個(gè)體現(xiàn)折联。另一個(gè)體現(xiàn)是,性能识颊,因?yàn)橐ㄟ^(guò)一個(gè)時(shí)間段來(lái)對(duì)遠(yuǎn)端節(jié)點(diǎn)狀態(tài)進(jìn)行確認(rèn)诚镰,那自然性能會(huì)有所下降,這又是不可避免的祥款。
而具體的raft算法清笨,那就等到下一節(jié)再說(shuō)吧。
總結(jié):
- 分布式一致性指的其實(shí)就是分布式異步環(huán)境下刃跛,要讓多個(gè)節(jié)點(diǎn)對(duì)系統(tǒng)狀態(tài)的改變能夠達(dá)成共識(shí)抠艾。
- 分布式系統(tǒng)一致性難,難在異步通信不可靠桨昙。由此衍生出了liveness和satefy取舍的問(wèn)題以及僵尸節(jié)點(diǎn)問(wèn)題检号,有了FLP impossibility定理。
- paxos/raft等算法通過(guò)一個(gè)安全時(shí)間段蛙酪,可以在某種程度上實(shí)現(xiàn)分布式系統(tǒng)的一致性齐苛。
PS:本篇大部分參考自端到端一致性,流系統(tǒng)Spark/Flink/Kafka/DataFlow對(duì)比總結(jié),只是里面有很多是講流處理系統(tǒng)的滤否。不過(guò)同樣是裂墻推薦脸狸,反正看過(guò)的都說(shuō)好。
以上~