網絡模型和故障模型

在本系列第一篇文章中咱們提到了Lamport Clock如何啓發人們在分佈式系統中開始使用新的的思惟方式, 並介紹了Sequential Consistency和Linearizability. 本篇爲分佈式系統一致性發展的第二篇長文,會介紹他們所延展出來的一些應用問題,讓你們更好的理解這兩種一致性模型。算法

在本篇正式開始以前, 咱們先定義一下分佈式系統中的網絡和故障的模型, 這部分稍微有點枯燥, 但很重要, 瞭解它們才能繼續研究更深層的問題。編程

分佈式系統中的網絡模型
同步網絡(synchronous network)
這裏的同步網絡和編程中的同步阻塞io和異步非阻塞io是兩回事, 不要弄混了。網絡

同步網絡是指:
i). 全部節點的時鐘漂移有上限
ii). 網絡的傳輸時間有上限
iii). 全部節點的計算速度同樣.架構

這意味着整個網絡按照round運行, 每一個round中任何節點都要執行完本地計算而且能夠完成一個任意大小消息的傳輸. 一個發出的消息若是在一個round內沒有到達, 那麼必定是網絡中斷形成的, 這個消息會丟失, 不會延遲到第二個round到達. 在現實生活中這種網絡比較少, 儘管不多, 同步網絡仍然是在計算機科學中是不可缺乏的一個模型, 在這種模型下能夠解決一些問題, 好比拜占庭式故障. 但咱們天天打交道的網絡大多都是異步網絡.異步

異步網絡(asynchornous network)
和同步網絡相反, 節點的時鐘漂移無上限, 消息的傳輸延遲無上限, 節點計算的速度不可預料. 這就是和咱們天天打交道的網絡類型. 在異步網絡中, 有些故障很是難解決, 好比當你發給一個節點一個消息以後幾秒鐘都沒有收到他的應答, 有可能這個節點計算很是慢, 可是也多是節點crash或者網絡延遲形成的, 你很難判斷究竟是發生了什麼樣的故障.async

Fault, Error and Failure
這不是繞口令, 你必定要區分他們的關係. 過去不少時候這些詞彙混用致使不少問題, 後來統一了這幾個詞的定義:分佈式

Fault: 在系統中某一個步驟偏離正確的執行叫作一個fault, 好比內存寫入錯誤, 可是若是內存是ECC的那麼這個fault能夠馬上被修復, 就不會致使error.post

Error: 若是一個fault沒能在結果影響到整個系統狀態以前被修復, 結果致使系統的狀態錯誤, 那麼這就是一個error, 好比不帶ECC的內存致使一個計算結果錯誤.設計

Failure: 若是一個系統的error沒能在錯誤狀態傳遞給其它節點以前被修復, 換句話說error被擴散出去了, 這就是一個failure.orm

因此他們的關係是fault致使error, error致使failure. 在分佈式系統中, 每一個節點很難肯定其它節點內部的狀態, 一般只能經過和其餘節點的交互監測到failure. 接下來咱們所說的故障通常都是指failure.

分佈式系統中的故障模型
在分佈式系統中, 故障可能發生在節點或者通訊鏈路上, 下面咱們按照從最普遍最難的到最特定最簡單的順序列出故障類型:

byzantine failures: 這是最難處理的狀況, 一個節點壓根就不按照程序邏輯執行, 對它的調用會返回給你隨意或者混亂的結果. 要解決拜占庭式故障須要有同步網絡, 而且故障節點必須小於1/3, 一般只有某些特定領域纔會考慮這種狀況經過高冗餘來消除故障. 關於拜占庭式故障你如今只要知道這是最難的狀況, 稍後咱們會更詳細的介紹它.

crash-recovery failures: 它比byzantine類故障加了一個限制, 那就是節點老是按照程序邏輯執行, 結果是正確的. 可是不保證消息返回的時間. 緣由多是crash後重啓了, 網絡中斷了, 異步網絡中的高延遲. 對於crash的狀況還要分健忘(amnesia)和非健忘的兩種狀況. 對於健忘的狀況, 是指這個crash的節點重啓後沒有完整的保存crash以前的狀態信息, 非健忘是指這個節點crash以前能把狀態完整的保存在持久存儲上, 啓動以後能夠再次按照之前的狀態繼續執行和通訊.

omission failures: 比crash-recovery多了一個限制, 就是必定要非健忘. 有些算法要求必須是非健忘的. 好比最基本版本的Paxos要求節點必須把ballot number記錄到持久存儲中, 一旦crash, 修復以後必須繼續記住以前的ballot number.

crash-stop failures: 也叫作crash failure或者fail-stop failures, 它比omission failure多了一個故障發生後要中止響應的要求. 好比一個節點出現故障後當即中止接受和發送全部消息, 或者網絡發生了故障沒法進行任何通訊, 而且這些故障不會恢復. 簡單講, 一旦發生故障, 這個節點 就不會再和其它節點有任何交互. 就像他的名字描述的那樣, crash and stop.

分佈式系統中的故障類型還有其餘的分類方法, 有些分類會把omission去掉, 有些會加入performance failures, 有些會把crash-stop和fail-stop根據故障檢測能力區分開, 此處介紹的是使用較爲普遍的一種分類方法. 它們的關係以下:

2

這四種故障中, 拜占庭式故障是很是難以解決的, Leslie Lamport證實在同步網絡下, 有辦法驗證消息真僞, 故障節點不超過1/3的狀況下才有可能解決. 在現實中, 這類問題解決成本很是高, 只有在很是關鍵的領域會考慮使用BFT(Byzantine Fault Tolerance)的設計. 好比NASA的航天飛機有5臺能夠抵抗各類射線影響的AP-101系列計算機, 其中四臺使用一樣的軟件運行, 另一臺獨立運行另一個獨立編寫版本的軟件. 空客A320有7臺計算機, 分別是三種硬件上運行的三套獨立編寫的軟件. 美國海軍的海狼級核動力攻擊型潛水艇(SSN-21)也採用了多組計算機控制. 絕大多數應用是不太考慮重力加速度和射線輻射對硬件的影響的, 稍後本文會介紹拜占庭將軍問題來具體解釋一下這類問題. 大多數分佈式應用主要是關注crash-recovery的狀況, 而crash-stop是一種過於理想化的狀況, 後面咱們在介紹Paxos算法的時候會給你們講解爲何這個過於理想化的故障模型會帶來什麼樣的問題.

Consensus問題
之因此要介紹Consensus問題是由於Consensus問題是分佈式系統中最基礎最重要的問題之一, 也是應用最爲普遍的問題, 他比其餘的分佈式系統的經典問題好比self-stabilization的實際應用要多, 咱們能夠經過介紹Consensus問題來更加深刻得介紹一下以前提到的Linearizability和Sequential Consistency.

Consensus所解決的最重要的典型應用是容錯處理(fault tolerannce). 好比在原子廣播(Atomic Broadcast)和狀態機複製(State Machine Replication)的時候, 咱們都要在某一個步驟中讓一個系統中全部的節點對一個值達成一致, 這些均可以概括爲Consensus問題. 可是若是系統中存在故障, 咱們要忽略掉這些故障節點的噪音讓整個系統繼續正確運行, 這就是fault tolerance. Consensus問題的難點就在於在異步網絡中如何處理容錯.

Consensus問題的定義包含了三個方面, 通常的Consensus問題定義爲:
termination: 全部進程最終會在有限步數中結束並選取一個值, 算法不會無盡執行下去.
agreement: 全部非故障進程必須贊成同一個值.
validity: 最終達成一致的值必須是V1到Vn其中一個, 若是全部初始值都是vx, 那麼最終結果也必須是vx.

Consensus要知足如下三個方面: termination, agreement 和 validity. 這三個要素定義了全部Consensus問題的本質. 其中termination是liveness的保證, agreement和validity是safety的保證, 分佈式系統的算法

liveness和safety就像一對死對頭, 關於liveness和safety的關係, 咱們將會在本系列後面的文章中介紹. 全部須要知足這三要素的問題均可以看作是Consensus問題的變體.

在異步網絡中, 若是是拜占庭式故障, 那麼Paxos和Raft也沒法解決這一類問題, 嚴格講這是沒有辦法解決的, 很長一段時間內咱們只看到在航天和軍事領域經過同步網絡解決此類問題. (直到Babara Liskov在2002年提出PBFT咱們才能夠在放鬆liveness的狀況下解決此類問題, 爲此Barbara Liskov得到了圖靈獎. 咱們可能會在未來的文章中介紹PBFT). 對於通常的應用來講拜占庭故障出現的機率過低而解決的成本實在是過高, 因此咱們通常不考慮拜占庭式故障. 咱們主要是關注crash-recovery failure的模型下的異步網絡. 這種狀況下根據FLP理論, 只要有一個故障節點, Paxos/Raft都是有可能進入無限循環而沒法結束的, 可是實際上這個機率很是低, 若是放鬆liveness的要求, 咱們認爲這種狀況下Paxos/Raft是能夠解決的. 如下介紹Consensus問題的時候咱們都不考慮拜占庭式故障, 咱們的故障模型是crash-recovery failures, 網絡模型是異步網絡.

在同步網絡中由於全部節點時間偏移有上限, 全部包的傳輸延遲也有上限, 節點會在一個round內完成計算而且傳輸完成, 因此一旦超過必定時間尚未收到返回的消息, 咱們就能夠肯定要麼網絡中斷要麼節點已經crash. 可是咱們現實當中都是異步網絡, 傳輸延遲是沒有固定上限的, 當很長時間一個節點都沒有返回消息的時候, 咱們不知道是這個節點計算速度太慢, 仍是已經crash了. 若是是這個節點計算太慢, 超時以後, 過了一會這個節點又把結果再發回來了, 這就超出crash-stop故障模型的範圍了, 這種狀況須要用crash recovery的模型來解決. 在異步網絡中沒法區分crash和包延遲會致使consensus問題很是難解決。

今天是分佈式系統發展史第二篇的第一部份內容,明天咱們將繼續發佈第二部份內容《兩階段提交和三階段提交的發展史》,敬請期待。

若是您想投稿給咱們,或者想轉發和採用咱們的稿件,請回復「合做」,小編會在2小時內回覆您的投稿和合做需求。

本文做者:Daniel,吳強, 現任點融網首席社交平臺架構師,前盛大架構師, 專一分佈式系統和移動應用, 有十三年的開發經驗, 目前在點融作最愛的兩件事情: 寫代碼和重構代碼。

隨着新一輪融資,點融網開始了大規模的擴張,須要各類優秀人才的加入,若是您以爲本身夠優秀,歡迎加入咱們!

相關文章
相關標籤/搜索