此次準備開啓一個新的系列來寫了,聊聊分佈式系統中的關注點。節奏不會排的太緊湊,計劃兩週一更吧。
本文是本系列的第二篇。是前一篇《不知道是否是最通俗易懂的《數據一致性》剖析了》的後續內容。git
前一篇可能講的過於通俗,逼格不高,不太受你們待見。。本篇會繼續堅持儘可能講的通俗易懂,堅信讓更多的人看懂纔有更大的價值。不過相對來講內容的專業度有所上升。github
已經對數據一致性問題作了一次剖析,那麼怎麼解決因爲故障致使的不一致問題呢?本文會圍繞「共識」這個點展開。算法
一致性問題實際上是一個「結果」,本質是因爲數據冗餘致使的,若是沒有冗餘,也就不會有一致性問題了。數據庫
分佈式系統裏的各個子系統之間之因此可以相互協做,就是由於其之間冗餘了相同的數據做爲「信物」,要否則我都不認識你的話,爲何要配合你幹活呢。因此這個「信物」變了,你得通知我,要否則我又不認識你了。這個「信物」變動達成一致性的過程稱做達成「共識」。因此:微信
一致性問題是結果,共識是爲達到這個結果所要通過的過程,或者說一種手段。
在分佈式系統中,冗餘數據的場景不限於此,由於規模越大的系統,越不能容忍某一個子系統出問題後產生蝴蝶效應,因此每每會作高可用。小明1號倒下了還有千千萬萬個小明X號在堅守崗位,理想中的全天候24小時提供服務~。高可用的本質是經過相同數據存儲多個副本,並均可對外提供服務。好比每一個小明X號都有一本《按摩指法白皮書》,誰請假了均可以由其它小明X號提供相同的按摩服務。可是這個本《按摩指法白皮書》改了,就得通知到每一個人,由於這是服務的所有和來源,因此在作了高可用的集羣中數據冗餘的問題更爲突出。網絡
實際上,若是分佈式系統中各個節點都能保證瞬時響應、無端障運行,則達成共識很容易。就好像咱們人同樣,在必定範圍內只要吼一嗓子,經過穩定的空氣傳播,相關人是否接收到這個消息,而且給出響應幾乎能夠是「瞬時」的。可是正如〖上篇,← 點我〗文中提到,這樣的系統只停留在想象中,響應請求每每存在延時,網絡會發生中斷,節點發生故障,甚至存在惡意節點故意要破壞系統。這就衍生出了經典的「拜占庭將軍問題」[1]。架構
咱們通常把「拜占庭將軍問題」分爲2種狀況來看待:less
這個問題的核心在於:分佈式
如何解決某個變動在分佈式網絡中獲得一致的執行結果,是被參與多方都認可的,同時這個信息是被肯定的,不可推翻的。
比如如何讓全部的小明X號收到的都是《按摩指法白皮書Ⅱ》,而不是其它的,而且把原來的那本銷燬掉。這個問題衍生出了不少「共識」算法,解決「拜占庭錯誤」的稱做Byzantine Fault Tolerance(BFT)類算法,解決「非拜占庭錯誤」的稱做Crash Fault Tolerance(CFT)類算法。從這個2個名字中也能夠看出,本質的工做就是「容錯」。有的小夥伴在平時的工做中可能對「容錯」的重要性感知沒那麼強烈,不就產生一個BUG或者異常數據麼,可是在航天領域,一個小錯誤可能致使整個發射的失敗,代價很是巨大。性能
對「拜占庭將軍問題」想深刻的瞭解的,能夠自行查閱相關資料,這裏就不展開了,文末附上提出時的論文。
咱們常見的軟件開發中通常不會考慮「拜占庭錯誤」,但它是區塊鏈項目的必需品。不過在主流的分佈式數據庫中,皆能看到「非拜占庭錯誤」的身影,諸如Tidb的Paxos算法,CockroachDB的Raft算法。雖然咱們你們在平常的coding中,對數據庫底層原理的瞭解並非必須項。可是隻要當咱們涉及到應用程序級別的高可用時,那麼至少「非拜占庭錯誤」是必需要面臨的一道坎。
BFT類型算法又有2個分支。「基於肯定性的」和「基於機率的」。
先聊聊「基於肯定性的」,此類算法表示一旦對某個結果達成共識就不可逆轉,即共識是最終結果。它的表明做是PBFT(Practical Byzantine Fault Tolerance)算法[2],自從有了央行背書(區塊鏈數字票據交易平臺),名聲更大了。算法的原理,以下圖:
▲圖片來源於網絡,版權歸原做者全部
拿軍隊來比喻,這裏的直線C能夠認爲是「總司令」,直線0是「軍長」,直線一、直線二、直線3都是「師長」,值得注意的是3號師長叛變了。整個過程這樣解釋:
真正深刻了解PBFT的話還有不少內容,這裏就不繼續展開了,有興趣的小夥伴自行查閱文末論文地址或者關注公衆號後直接後臺回覆「一致性」打包下載。
再聊聊「基於機率的」,此類算法的共識結果則是臨時的,隨着時間推移或某種強化,共識結果被推翻的機率愈來愈小,成爲事實上的最終結果。它的表明做是PoW(Proof of Work)算法,曾經高達2W美圓/個的比特幣就是基於這個算法來實現的。算法的原理拿「修仙」來作個簡單的比喻(實際比特中的算法比這更復雜):
被誤判的機率公式是: 0.5 ^ 個數,若是個數=6的話,誤判的機率是1.5625%。若是個數=10的話,就已是0.09765625%了,指數級降低。
值得注意的是,「基於肯定性的」和「基於機率的」對於不合做節點的標準是不一樣的,前者至多能容忍1/3,後者是小於1/2。
正如上面所說CFT類算法解決的是分佈式系統中存在故障,但不存在惡意節點的場景(便可能消息丟失或重複,但無錯誤消息)下的共識達成問題。「拜占庭將軍問題」的提出者Leslie Lamport也在他另外的論文[3]中提出過「Paxos問題」,與這類似。在論文中經過一個故事類比了這個問題,以下:
希臘島嶼Paxon 上的「 執法者」在「 議會大廳」中表決經過『 法律』,並經過「 服務員」傳遞紙條的方式交流信息,每一個「 執法者」會將經過的『 法律』記錄在本身的「 帳目」上。問題在於「 執法者」和「 服務員」都不可靠,他們隨時會由於各類事情離開「 議會大廳」,並隨時可能有新的「 執法者」進入「 議會大廳」進行法律表決。使用何種方式可以使得這個表決過程正常進行,且經過的『法律』不發生矛盾。
—— 百度百科
這裏的關鍵對象在咱們的系統中,能夠類比爲:
Leslie Lamport本身也提出瞭解決這個問題的算法,「Paxos」算法[4]。這個算法的關鍵由如下3個定義來體現:
這3點僅僅是保證一致性的最關鍵部分,所有內容還有不少。有興趣的小夥伴自行查閱文末論文地址或者關注公衆號後直接後臺回覆「一致性」打包下載。
「Paxos」算法是一種無領導人(Leaderless)算法,實現比較複雜,因此產生了不少變種來簡化它,其中名氣最大的應該是「Raft」,2013年才問世。「Raft」算法是一種領導人(Leadership)的算法。由如下2個過程保證達成共識:
雖然跟隨者的投票秉承先到先得,可是仍是會遇到多個term相同的候選人得到了相同票數(簡稱「分割投票問題」),那麼進行新一輪投票,直到決出勝負爲止。因爲Raft用隨機定時器來自增term,加上網絡是不穩定的,因此再次遇到相同票數的機率就大大下降了。
完整的過程更復雜一些,有一個Raft算法的動畫推薦給你們,有興趣的能夠了解一下:http://thesecretlivesofdata.c...。
題外話,你們常常用的Zookeeper裏的「ZAB」(ZooKeeper Atomic Broadcast)算法也是CFT類算法,是以Fast Paxos算法爲基礎實現的。
回過頭來看,咱們發現,想要更嚴謹的一致性,那麼就須要增長相互通信確認的次數,可是這會致使性能低下,正如PBFT和Paxos同樣。可是分佈式系統就是這樣,處處都須要Balance,找到最適合的纔是最重要的。
聊完了數據層面的「共識」問題,咱們下回再聊聊「分佈式事務」的問題,圍繞着常見的CAP、BASE理論展開。
最後若是說想成爲數據一致性專家,問有沒有捷徑的話。去閱讀老爺子Leslie Lamport的論文就是捷徑,他的我的主頁:http://www.lamport.org/ 。
▶ 微信後臺回覆「 一致性」關鍵字,可打包下載喲~
[1]《The Byzantine Generals Problem, ACM Transactions on Programming Languages and Systems》,Leslie Lamport,1982。
連接: https://www.microsoft.com/en-...
[2]《Practical Byzantine Fault Tolerance》,Miguel Castro&Barbara Liskov,1999。
連接: http://101.96.10.63/pmg.csail...
[3]《The Part-Time Parliament》,Leslie Lamport,1998。
連接: https://www.microsoft.com/en-...
[4]《In Search of an Understandable Consensus Algorithm》,Diego Ongaro&John Ousterhout,2013
連接: https://raft.github.io/raft.pdf
做者:Zachary(我的微信號:Zachary-ZF)
微信公衆號(首發):跨界架構師。<-- 點擊查閱近期熱門文章
按期發表原創內容:架構設計丨分佈式系統丨產品丨運營丨一些深度思考。
掃碼加入小圈子 ↓