面對可能出現的網絡延遲,不可預估的請求流量等狀況,設計一個分佈式系統,咱們一般圍繞系統高可用,數據一致性的目標去規劃和實現,想要徹底實現這個目標,卻並不是易事。由此,分佈式系統領域誕生了一個基本定理,即 CAP 定理,用於指導分佈式系統的設計,從系統高可用,數據一致性,網絡容錯三個角度將分佈式系統的特性抽成一個分區容錯一致性模型。這樣一來,讓系統設計者只需根據業務場景特色,進行權衡設計適合業務場景的分區容錯一致性模型便可,很大程度簡化了分佈式系統設計的難度。網絡
也所以,CAP 定理是架構師所必需要掌握的內容,它影響着架構師對分佈式系統的技術選型,技術決策。既然如此重要,接下來,咱們就一塊兒學習下 CAP 定理吧。架構
CAP 定理最初是由加州大學伯克利分校的計算機科學家埃裏克·布魯爾(Eric Brewer)在 2000 年的 ACM PODC 上提出的一個猜測,也所以被叫作布魯爾定理。後來在 2002 年,麻省理工學院的賽斯·吉爾伯特(Seth Gilbert)和南希·林奇(Nancy Lynch)發表了 CAP 定理的證實,讓它成爲分佈式系統領域公認的一個定理。分佈式
CAP 定理指出了,在一個跨區域網絡鏈接,共享數據的分佈式系統中,一致性(Consistency),可用性(Availability)和分區容錯性(Partition Tolerance) 這三個約束屬性最終只能同時知足二個。學習
下面是關於這三個屬性的簡單描述:架構設計
須要注意的是,CAP 描述了一個常規的分佈式系統場景:有網絡鏈接,且數據跨節點進行共享。若是在整個系統中,數據只有一份,而且其餘節點沒有對應的副本,也不須要進行跨節點的數據共享,這樣分佈式系統就不是 CAP 關心的對象了,也談不上結合 CAP 定理去設計和實施。設計
瞭解 CAP 基本概念以後,咱們再來分別對 C,A,P 三個屬性進一步學習下,加深對 CAP 的理解。3d
這裏的一致性從不一樣角度有着各自的描述方式,在分佈式系統中表現是每一個節點的數據是相同;而對於客戶端,表現是讀操做所獲得的結果永遠是最新寫入的。其中須要明確的是,對於分佈式系統節點來講,是可能出現某個時刻擁有不一樣的數據的狀況:若是在某個節點執行原子性操做時,對於執行過程當中的節點數據跟其餘節點就並不徹底一致,只有原子性操做執行完成後,節點的數據纔會繼續保持同步。好比常見的事務操做,只有事務提交後,客戶端才能讀取到事務寫入的數據,失敗則回滾爲舊的數據,不會出現讀取事務中間寫入數據的狀況。cdn
一致性要求了在分佈式環境下的操做要就像在單機上完成的同樣,當客戶端發起寫請求時,收到寫請求的節點會及時響應,並將更新的數據同步到另外一個節點,保證數據一致性。具體的工做流程,以下所示:對象
一致性強調了數據的強一致,這一點要求對於一些系統能夠說是十分重要的。好比電商系統的庫存扣減,金融系統的轉帳扣款等場景,任何出現一致性的問題,均可能會形成很嚴重的後果。blog
介紹完一致性,再來看下可用性,雖然可用性概念相對簡單,但重要程度跟一致性同樣。要讓系統知足可用性,就是要保證不管除了全部節點出現故障的狀況外,系統都能返回有效的響應,容許響應給客戶端是舊的數據,但不能出現響應失敗,超時的狀況。
可用性強調的是服務可用,但不保證數據的正確性。用一個簡單的例子來描述分佈式系統的可用性以下:容許客戶端向節點 1 或者節點 2 發起讀操做,當其中某一個節點故障了,無論節點間數據是否一致,只要有節點服務能收到請求,就響應 X 的值,這樣就說明這兩個節點服務是知足可用性。
在可用性的描述,還值得一提的是關於什麼算有效的響應。要返回有效的響應,不能超時,也不能出錯,結果不必定是正確的,好比返回了舊數據,可是客戶端接收到後是能進行正常業務處理的。
講完 C 和 A 以後,最後再講一下 P: 分區容錯性。因爲分佈式系統多個節點每每部署在多個網絡環境下進行相互通訊,就不免出現一些網絡故障,如網絡丟包,網絡消息延遲,網絡中斷等狀況,會致使節點間的通訊出現問題,數據同步操做沒法完成,分區容錯性就要求了系統即便在網絡分區出現的狀況下,能仍繼續對客戶端提供服務。
由於分佈式系統與單機不一樣,它涉及到了多節點間的通訊和數據交互,避免不了網絡問題,若是沒有分區容錯性,就意味着系統不容許出現節點間的通訊出現任何錯誤,錯誤就意味着系統不可用,這在絕大數系統中沒法接受的。所以對節點間的分區故障容錯是必需要考慮的,也是 CAP 定理中分區容錯性一般首先要保證的緣由。
瞭解完 CAP 定理的一致性(C),可用性(A)和分區容錯性(P)以後,咱們再來看下如何使用這個定理。CAP 定理指明瞭 C,A,P三個屬性沒法同時知足,而在必有網絡交互和數據同步的狀況下,就必定會有延遲和數據丟失的狀況,對於這種狀況咱們又必須接受且保證系統不能掛掉。因此分區容錯性是必需要保證的,剩下的就是在一致性 (C)和可用性(A)之間作選擇了。選擇了一致性,保證數據正確性,但也意味系統可能存在不可用的狀況;而選擇可用性,保證服務的高可用,但也意味數據可能出現不一致性的狀況。接下來就探討下應用採用 CP 架構,AP 架構所各自的特色,以及如何根據不一樣的分佈式場景選擇適合的架構策略。
對於 CP 架構的分佈式系統來講,爲了保證一致性,當出現網絡分區後,若是節點 1 上數據 X 已經更新爲 2,但因爲節點 間數據同步的通道已經中斷,節點 1 數據沒法同步到節點 2,節點 2 上的數據 X 仍是 1。此時若是客戶端訪問節點 2 的數據 X,節點 2 就須要返回錯誤,提示系統發生了錯誤,直到節點間的數據保持同步。固然這樣的處理方式明顯違背了可用性的要求,所以在 CAP 定理只能知足 CP。
若是一個分佈式場景須要很強的一致性,或者能容忍系統長時間無響應可是數據要保持一致的狀況,就比較適合使用 CP 架構設計對應的分佈式系統。這樣的系統一旦發生網絡分區會致使數據沒法同步狀況,就要犧牲系統的可用性,直到節點數據達到一致後再響應。在開源社區中採用 CP 架構的應用很多,好比 Redis,HBase,MongoDB,ZooKeeper,Etcd,Consul 等都是放棄了必定可用性而選擇 CP 屬性。
若是採用 AP 架構設計的分佈式系統,爲了保證可用性,當網絡分區發生後,一樣節點 1 上數據 X 已經更新爲 2,但因爲節點間數據同步的通道已經中斷,節點 1 數據沒法同步到節點 2,節點 2 上的數據 X 仍是 1。這是客戶端訪問節點 2 獲取數據 X 時,收到是正常的響應,舊數據 X = 1,而實際上當前最新的數據 X 已是 2 了,這裏就不知足一致性的要求了,所以在 CAP 定理只能知足 AP。
一樣適合 AP 的場景有不少,好比一些查詢系統,電商系統的商品查詢等,大多數爲了保證系統的可用性,而犧牲必定的數據一致性,這樣也保證了用戶體驗,在開源界中採用 AP 模型的典型應用有 Eurka,Cassandra。
提到了 CAP 定理,大多數人都認爲不管什麼狀況,分佈式系統只能在 C 和 A 中選擇一個。但這裏的前提是系統發生了網絡分區狀況,若是系統沒有發生網絡分區的狀況,也就是說 P 不存在的時候,咱們就沒有必要放棄 C 或者 A,所以進行架構設計時也應該考慮沒有分區狀況下如何保證 CA。除此以外,一個分佈式系統不必定只能從 AP 與 CP 中作選擇,內部不一樣模塊所應對的場景也不一樣,徹底有多是一個模塊採用 AP 架構,另外一個模塊採用 CP 架構。做爲優秀的架構師,不該該受到大多數人對 CAP 定理所認識的侷限,設計出符合自身業務場景的分佈式系統纔是重中之重。
本文主要了解和認識 CAP 定理,以及每一個 C,A,P 的含義,以及 CAP 定理的應用。掌握 CAP 定理,對架構師來講很是重要。由於對於分佈式系統來講,網絡故障在所不免,如何在出現網絡故障的時候,維持系統按照正常的行爲邏輯運行就顯得尤其重要。一個合格的架構師須要是能結合實際的業務場景和具體需求,基於 CAP 定理來進行權衡和設計可用且穩定的分佈式系統。
CAP theorem - Wikipedia en.wikipedia.org/wiki/CAP_th…
想成爲架構師,你必須知道CAP理論 time.geekbang.org/column/arti…
CAP定理:三選二,架構師必須學會的取捨 time.geekbang.org/column/arti…
本文由博客一文多發平臺 OpenWrite 發佈!