拜占庭將軍問題和FLP的啟示

Byzantine Generals Problem

昨天那篇文章提到的Two General Paradox實(shí)際上是一個弱化的Byzantine Generals Problem. 1982年, Leslie Lamport和另外兩位科學(xué)家年發(fā)表了一篇論文闡述 [The Byzantine Generals Problem, ACM Transactions on Programming Languages and Systems,Volume 4 Issue 3, July 1982 Pages 382-401] 描述了更一般化的情況, 這種情況下不僅是網(wǎng)絡(luò)會有故障, 節(jié)點(diǎn)本身也會有不按照邏輯執(zhí)行的問題. 比如一個叛徒將軍亂發(fā)消息或者不按照程序邏輯執(zhí)行. 完整的拜占庭將軍問題更加復(fù)雜, 必須加以特定場景的假設(shè)才能解決, 比如同步網(wǎng)絡(luò). 這個問題比較復(fù)雜, 本文只是簡要介紹一下.

在同步網(wǎng)絡(luò)中, 有3f+1個節(jié)點(diǎn), 如果故障節(jié)點(diǎn)不超過f個, 那么這個問題是可以解決的. 我們這里不做嚴(yán)格證明, 但是可以簡單解釋一下原因岛宦。

我們考慮最基礎(chǔ)的一種情況, 假設(shè)有三個將軍, 只有一個叛徒. 如果A是叛徒, 那么A可能會給B發(fā)出進(jìn)攻(1), 然后給C發(fā)出撤退(0)的命令. 當(dāng)B和C互相同步信息的時候他們會發(fā)現(xiàn)兩個不一致的信息. 但是B和C誰也無法判斷誰是叛徒, 比如從B的角度來看, 他無法判斷A是叛徒或者C是叛徒. 所以三個將軍里有一個叛徒是無法解決的. 如果消息可以防止偽造, 那么在同步網(wǎng)絡(luò)中叛徒達(dá)到1/3也是可以解決的. 下圖右邊從C的角度來看, 因?yàn)橄⑹钦鎸?shí)無法偽造的, 那么很明顯A是叛徒. 由此可以推導(dǎo)到3f+1的情況.

但是同步網(wǎng)絡(luò)現(xiàn)實(shí)生活中太少, 如果要考慮在異步網(wǎng)絡(luò)之中, 拜占庭將軍問題是非常難解決的, 實(shí)際上根據(jù)FLP定理, 異步網(wǎng)絡(luò)中是沒有完全同時保證safety和liveness的一致性算法的. 但是在實(shí)際工程中我們?nèi)绻潘蒷iveness的要求, 是有實(shí)際可用的算法的, 這個算法進(jìn)入無限循環(huán)的概率非常非常低. 1999年Miguel Castro和Barbara Liskov提出了PBFT算法(Practical Byzantine Fault Tolerance), 這個算法可以在異步網(wǎng)絡(luò)中不保證liveness的情況下解決拜占庭將軍問題. 雖然不保證Liveness但是這個算法進(jìn)入無限循環(huán)的概率非常低, 在工程中是完全可用的. 實(shí)際上他們實(shí)現(xiàn)了一個PBFT的分布式NFS文件服務(wù)器, 最壞的時候性能只下降了24%! 為此BarbaraLiskov獲得了2008年代圖靈獎. 有興趣的同學(xué)可以自己去看 Practical Byzantine Fault Tolerance and Proactive Recovery. (ACM Transactions on Computer Systems, Vol. 20, No. 4, November 2002, Pages 398–461).

順便提一句, 面向?qū)ο笾械腖iskov替換原則也是她提出的.

圖片來源:維基百科, Barbara Liskov 2010


FLP Impossibility

分布式事務(wù)作為Consensus類型問題, 在異步網(wǎng)絡(luò)中非常難實(shí)現(xiàn). 很多科學(xué)家們做了很多偉大的嘗試, 包括2PC, 3PC, 等等, 但是1985年的時候, 一個重要的論文告訴了我們答案, 這就是著名的FLP Impossibility:

No completely asynchronous consensus protocol can tolerate even a single unannounced process death. [ Impossibility of Distributed Consensus with One Faulty Process,Journal of the Association for Computing Machinery, Vol. 32, No. 2, April 1985]

在異步網(wǎng)絡(luò)環(huán)境中只要有一個故障節(jié)點(diǎn), 任何Consensus算法都無法保證正確結(jié)束. (這里unannounced process death是指一個進(jìn)程停止工作了但是其它節(jié)點(diǎn)不知道, 其它節(jié)點(diǎn)認(rèn)為是消息延遲或者這個進(jìn)程特別慢. FLP假設(shè)沒有拜占庭的故障節(jié)點(diǎn), 那種情況過于困難, 故障在這里的定義是指進(jìn)程停止嘗試讀取消息, 相當(dāng)于crash-stop).

FLP中設(shè)計的模型是一個比現(xiàn)實(shí)情況要更可靠的模型, 當(dāng)然了, 如果連更可靠的模型下一致性問題失效那么現(xiàn)實(shí)中更寬松的環(huán)境當(dāng)然也是失效的. FLP還假設(shè)異步網(wǎng)絡(luò)是可靠的, 盡管有延遲但是所有的消息都會投遞一次且僅一次, 每個進(jìn)程只會寫入一次狀態(tài), 然后就進(jìn)入了decision state, 這是一個很強(qiáng)的保證, 幾乎沒有任何網(wǎng)絡(luò)能達(dá)到這樣的可靠性. FLP并不要求所有非故障節(jié)點(diǎn)都達(dá)成一致, 只要有一個進(jìn)程進(jìn)入decision state就算達(dá)成一致了, 而且一致結(jié)果只能是屬于{0, 1}, 這也是非常”容易”的agreement約束. 加上前面還提到最多只有一個進(jìn)程發(fā)生故障, 相對于現(xiàn)實(shí)情況這已經(jīng)是一個極端可靠的環(huán)境了, 但是在這樣可靠的環(huán)境中仍然無法有一個一致性算法存在! 更不用說真實(shí)世界中的網(wǎng)絡(luò)分區(qū)問題和拜占庭式問題了. FLP的證明告訴我們一致性算法的liveness是無法保證的, 如果你要safety那么就會可能進(jìn)入無限循環(huán), 每次狀態(tài)變化都會可能保持當(dāng)前的狀態(tài)是可分支的(bivalent). FLP的嚴(yán)格證明很有趣, 但限于篇幅這里就不做介紹了. 有興趣的同學(xué)可以去看原論文, 如果你覺得里面的數(shù)學(xué)語言比較晦澀, 可以看我寫的一篇白話文的證明過程描述(鏈接:http://danielw.cn/FLP-proof/).

圖片來源:MIT, Nancy Lynch, 兩次Dijkstra獎獲得者.

所有consensus問題最終在異步網(wǎng)絡(luò)上只要有一個故障節(jié)點(diǎn)就都無法達(dá)成完全一致并結(jié)束. 這個理論的證明非常重要, 它終止了多年的爭論, 現(xiàn)在你可以省省力氣了, 不要再浪費(fèi)精力去試圖設(shè)計一個能在異步網(wǎng)絡(luò)上能夠容忍各種故障并保持一致的系統(tǒng)了. 比如分布式事務(wù)是永遠(yuǎn)無法實(shí)現(xiàn)單體應(yīng)用級別的一致性的.

無論是Paxos還是Raft算法, 理論上都可能會進(jìn)入無法表決通過的死循環(huán)(但是這個概率其實(shí)是非常非常低的), 但是他們都是滿足safety的, 只是放松了liveness的要求, Barbara Liskov的PBFT也是這樣. 在實(shí)際應(yīng)用中, 上下游系統(tǒng)之間的一致性除了通過2PC或者Paxos Commit來實(shí)現(xiàn), 我們也可以通過其他方式來實(shí)現(xiàn)最終的一致, 來避免2PC的缺點(diǎn). 現(xiàn)實(shí)中你不得不接受短時間的不一致在分布式系統(tǒng)中是一種常態(tài)的事實(shí). CAP理論的提出者Eric Brewer曾經(jīng)這樣說過:

So the general answer is you allow things to be inconsistent and thenyou find ways to compensate for mistakes, versus trying to prevent mistakes altogether. In fact, the financial system is actually not based on consistency, it's based on auditing and compensation. They didn't know any thing about the CAP theorem, that was just the decision they made in figuring out what they wanted, and that's actually, I think, the right decision.

舉個例子,實(shí)際上你從A銀行往B銀行轉(zhuǎn)賬實(shí)際上是沒有兩階段提交或者分布式事務(wù)的, 金融行業(yè)是一個古老的行業(yè), 在計算機(jī)出現(xiàn)之前銀行就已經(jīng)出現(xiàn)了, 金融行業(yè)有一點(diǎn)非常值得我們借鑒, 那就是WORM(write once read many). 金融行業(yè)把不一致當(dāng)做常態(tài)而非異常.舉個例子, 會計記賬的時候, 如果發(fā)現(xiàn)前面有一筆預(yù)付記錄或者錯誤記錄, 會計不會用橡皮抹掉那條記錄再改成正確的, 會計只會在最后面加一筆記錄來抵消前面的錯誤, 或者按照差額加一筆抵沖的記錄. 任何記錄只能寫入一次, 然后再也不會改變. 我們假設(shè)沒有人民銀行作為中間節(jié)點(diǎn), 把轉(zhuǎn)賬簡化為A銀行直接給B銀行轉(zhuǎn)賬, 在轉(zhuǎn)賬過程中如果A已經(jīng)扣款并通知了B,但是B發(fā)現(xiàn)這個賬號由于洗錢被鎖定了, 不能入款, 那么B返回拒絕消息給A, 這時候A可以再追加一筆補(bǔ)償交易, 把剛才扣掉的錢補(bǔ)償回來. 整個過程可能是幾秒鐘, 也可能是幾分鐘, 也有可能是第二天(比如網(wǎng)絡(luò)故障, 重試多次后放棄, 對賬時發(fā)現(xiàn)). 在任何一個步驟發(fā)生故障, 用戶都會經(jīng)歷一定時間的不一致, 從前面的討論我們知道2PC如果允許超時回滾, 2PC也無法消除這個不一致的時間窗口, 但是只要有歷史記錄我們就可以通過自動補(bǔ)償或者每日對賬去補(bǔ)償, 讓數(shù)據(jù)重新一致. 這種事務(wù)可以很好地忍耐各種故障, 包括網(wǎng)絡(luò)分區(qū), 只要每個消息都有全局唯一的id或者消息是冪等的即可. 當(dāng)網(wǎng)絡(luò)恢復(fù)時任何一個節(jié)點(diǎn)都可以根據(jù)消息id輕松地去掉重復(fù)的消息, 當(dāng)消息丟失時, 可以稍后重試或者每天對賬.

如果事務(wù)包含特別復(fù)雜的計算, 或者涉及了線下的物流或者多方交易, 那么這樣的事務(wù)可能需要幾天才能完成, 這種長事務(wù)(Long Lived Transaction) 在2PC中更是無法處理, 我們總不能去鎖定這些數(shù)據(jù)幾天吧? 1987年普林斯頓大學(xué)的Garcia-Molina和Salem發(fā)表了一篇論文提出了saga的概念. 一個長事務(wù)T中的操作可以拆分為彼此獨(dú)立的本地事務(wù)T1, T2, T3, 那么就可以稱之為saga. 其中的每一個Ti都有一個相應(yīng)的補(bǔ)償事務(wù)Ci. 如果部分Ti失敗了需要Ci來修復(fù)回原始狀態(tài),Ci不會直接把數(shù)據(jù)庫改回原先的狀態(tài), Ci通常是像前面說的會計的做法追加修正內(nèi)容去抹平Ti帶來的變化. 下圖中事務(wù)參與者有A,B, C, 每次發(fā)起的事務(wù)都有一個全局唯一的id, 參與者之間的消息在網(wǎng)絡(luò)故障時可以重發(fā) (可以通過id去重復(fù)消息, 或者保證冪等操作). 假如T3在C中執(zhí)行時失敗了, 如果T3已經(jīng)提交了或者這個系統(tǒng)不支持回滾, 那么必須使用C3來補(bǔ)償T3帶來的變化. 然后發(fā)消息給B, B會執(zhí)行C2去補(bǔ)償T2, 然后B可以選擇繼續(xù)通知A去回滾, 或者稍后等外部條件發(fā)生變化再執(zhí)行T2, 然后讓C去重試. 這樣整個系統(tǒng)變成了一個狀態(tài)機(jī),參與者之間雖然有可能不一致,一個訂單或者一筆交易一定會處于狀態(tài)機(jī)的某一個狀態(tài), 整個事務(wù)的過程仍然是整體可以追溯的.

Saga這種方法并不適合所有的情況, 它也不是銀彈, 但是它是比2PC/3PC更適合來解決分布式事務(wù). 2PC/3PC的思路是想在源頭上阻止分布式事務(wù)不一致的產(chǎn)生, 但這是不可能實(shí)現(xiàn)的. 不一致是常態(tài), 不是異常, 異步網(wǎng)絡(luò)中能容忍節(jié)點(diǎn)故障的total correct的consensus算法不存在简卧。

本文作者:Daniel吳強(qiáng)(點(diǎn)融黑幫)扣墩,現(xiàn)任點(diǎn)融網(wǎng)首席社交平臺架構(gòu)師,前盛大架構(gòu)師, 專注分布式系統(tǒng)和移動應(yīng)用, 有十三年的開發(fā)經(jīng)驗(yàn), 目前在點(diǎn)融做最愛的兩件事情: 寫代碼和重構(gòu)代碼鞍爱。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市专酗,隨后出現(xiàn)的幾起案子硬霍,更是在濱河造成了極大的恐慌,老刑警劉巖笼裳,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異粱玲,居然都是意外死亡躬柬,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門抽减,熙熙樓的掌柜王于貴愁眉苦臉地迎上來允青,“玉大人,你說我怎么就攤上這事卵沉〉唢保” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵史汗,是天一觀的道長琼掠。 經(jīng)常有香客問我,道長停撞,這世上最難降的妖魔是什么瓷蛙? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任悼瓮,我火速辦了婚禮,結(jié)果婚禮上艰猬,老公的妹妹穿的比我還像新娘横堡。我一直安慰自己,他們只是感情好冠桃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布命贴。 她就那樣靜靜地躺著,像睡著了一般食听。 火紅的嫁衣襯著肌膚如雪胸蛛。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天碳蛋,我揣著相機(jī)與錄音胚泌,去河邊找鬼。 笑死肃弟,一個胖子當(dāng)著我的面吹牛玷室,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播笤受,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼穷缤,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了箩兽?” 一聲冷哼從身側(cè)響起津肛,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎汗贫,沒想到半個月后身坐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡落包,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年部蛇,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咐蝇。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡涯鲁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出有序,到底是詐尸還是另有隱情抹腿,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布旭寿,位于F島的核電站警绩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏盅称。R本人自食惡果不足惜房蝉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一僚匆、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧搭幻,春花似錦咧擂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間盒件,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工皇筛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坠七。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓水醋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親彪置。 傳聞我的和親對象是個殘疾皇子拄踪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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

  • 分布式系統(tǒng)面臨的第一個問題就是數(shù)據(jù)分布,即將數(shù)據(jù)均勻地分布到多個存儲節(jié)點(diǎn)拳魁。另外惶桐,為了保證可靠性和可用性,需要將數(shù)據(jù)...
    olostin閱讀 4,550評論 2 26
  • 拜占庭將軍問題很多人可能聽過潘懊,但不知道是什么意思姚糊,本文從非專業(yè)的角度來講講,拜占庭將軍問題到底是說什么的授舟。 拜占庭...
    蘇江同學(xué)閱讀 39,914評論 29 68
  • 昨天我們介紹了拜占庭將軍問題和FLP Impossibility, 我們知道了在異步網(wǎng)絡(luò)中的total corre...
    點(diǎn)融黑幫閱讀 1,550評論 0 6
  • 想你
    蓋世英雄hero閱讀 267評論 0 0
  • 1.冒泡排序2.選擇排序3.插入排序4.快速排序5.堆排序6.希爾排序7.歸并排序8.計數(shù)排序9.桶排序10.基數(shù)...
    IT楓閱讀 637評論 0 5