1. 程式人生 > 其它 >架構設計之「 CAP 定理 」

架構設計之「 CAP 定理 」

在計算機領域,如果是初入行就算了,如果是多年的老碼農還不懂 CAP 定理,那就真的說不過去了。CAP可是每一名技術架構師都必須掌握的基礎原則啊。

現在只要是稍微大一點的網際網路專案都是採用 分散式 結構了,一個系統可能有多個節點組成,每個節點都可能需要維護一份資料。那麼如何維護各個節點之間的狀態,如何保障各個節點之間資料的同步問題就是大家急需關注的事情了。
CAP定理是分散式系統中最基礎的原則。所以理解和掌握了CAP,對系統架構的設計至關重要。


一、什麼是 CAP?
「 CAP定理 」又被稱為 布魯爾定理,它提出對於一個分散式系統而言,不能同時滿足以下三點:

  • Consisteny(一致性)
  • Availability(可用性)
  • Partition tolerance(分割槽容錯性)

也就是說CAP定理指明瞭,任何分散式系統只能同時滿足這三項中的兩項。

如上圖,如果是最多同時滿足兩項,那我們可以有三個組合:CA、CP、AP。在聊這三個組合之前,我們先分別看一下 Consisteny(一致性)、Availability(可用性)、Partition tolerance(分割槽容錯性)的含義。
假設某個系統當前有兩個節點A和B,兩個節點分別可以由Actor進行讀寫,兩個節點之間的資料會自動完成同步。

  1. Consisteny(一致性)
    一致性的要求是指,對於任何客戶端(上圖Actor)來說,每次的讀操作,都能獲得最新的資料。即,當有客戶端向A節點寫入了新資料之後,其它客戶端從B節點中進行讀操作所獲得的資料必須也是最新的,是與A節點資料保持一致的。
  2. Availability(可用性)
    可用性的要求是指,每個請求都能在合理的時間內獲得符合預期的響應(不保證獲取的結果是最新的資料)。
    按照上圖來看就是,客戶端只要向A節點或B節點發起請求後,只要這兩個節點收到了請求,就必須響應給客戶端,但不需要保證響應的值是否正確。
  3. Partition tolerance(分割槽容錯性)
    分割槽容錯性是指,當節點之間的網路出現問題之後,系統依然能正常提供服務。

講完了C、A、P的含義和要求,我們繼續來看看它們之間如何組合使用。
二、CAP 怎麼應用?
先把視野回到這張圖上:

雖然我們知道有 CA、CP、AP 三種組合方式,但是在分散式系統的結構下,網路是不可能做到100%可靠的。既然網路不能保證絕對可靠,那 P(分割槽容錯性)就是一個必選項了。原因如下:
如果選擇 CA組合,放棄 P(分割槽容錯性)。還是以最上面的圖中A和B節點來舉例,當發生節點間網路故障時,

手機靚號交易地圖為了保證 C(一致性),那麼就必須將系統鎖住,不允許任何寫入操作,否者就會出現節點之間資料不一致了。但是鎖住了系統,就意味著當有寫請求進來的時候,系統是不可用的,這一點又違背了 A(可用性)原則。
因此分散式系統理論上是不可能有CA組合的,所以我們只能選擇 CP 和 AP組合架構。
下面我們來詳細看一下 CP架構 和 AP架構的特點:

  1. CP 架構
    CP架構即 Consisteny(一致性)與 Partition tolerance(分割槽容錯性)的組合。


如上圖,由於網路問題,節點A和節點B之前不能互相通訊。當有客戶端(上圖Actor)向節點A進行寫入請求時(準備寫入Message 2),節點A會不接收寫入操作,導致寫入失敗,這樣就保證了節點A和節點B的資料一致性,即保證了Consisteny(一致性)。
然後,如果有另一個客戶端(上圖另一個Actor)向B節點進行讀請求的時候,B請求返回的是網路故障之前所儲存的資訊(Message 1),並且這個資訊是與節點A一致的,是整個系統最後一次成功寫入的資訊,是能正常提供服務的,即保證了Partition tolerance(分割槽容錯性)。
上述情況就是保障了CP架構,但放棄了Availability(可用性)的方案。

  1. AP 架構
    AP架構即 Availability(可用性)與 Partition tolerance(分割槽容錯性)的組合架構。


如上圖,由於網路問題,節點A和節點B之前不能互相通訊。當有客戶端(上圖Actor)向節點A進行寫入請求時(準備寫入Message 2),節點A允許寫入,請求操作成功。但此時,由於A和B節點之前無法通訊,所以B節點的資料還是舊的(Message 1)。當有客戶端向B節點發起讀請求時候,讀到的資料是舊資料,與在A節點讀到的資料不一致。但由於系統能照常提供服務,所以滿足了Availability(可用性)要求。
因此,這種情況下,就是保障了AP架構,但其放棄了 Consisteny(一致性)。

三、CAP 注意事項?
瞭解了CAP定理後,對於開發者而言,當我們構建服務的時候,就需要根據業務特性作出權衡考慮,哪些點是當前系統可以取捨的,哪些是應該重點保障的。
即使是在同一個系統中,不同模組的資料可能應用的CAP架構都是不同的。舉個例子,在某個電商系統中,屬於使用者模組的資料(賬密、錢包餘額等)對一致性的要求很高,就可以採用CP架構。而對於一些商品資訊方面的資料對一致性要求沒那麼高,但為了照顧使用者體驗,所以對可用性要求更高一些,那麼這個模組的資料就可以採用AP架構。
另外,雖然上面第二節講到過我們只能選擇CP和AP,無法選擇CA。但這句話成立的前提條件是在系統發生了網路故障的情況下。然而,網路故障的概率在系統的整個生命週期中佔比是很小的,因此我們在設計的時候,雖然要考慮網路問題下的方案,但也要考慮網路正常情況下的方案,即在網路正常情況下,CA是可以實現的,我們也需要去保證在絕大多數時間下的CA架構。
再者,即使我們按照CAP定理,三個中只能取其二,但不代表我們只需要保障其中的兩點,而完全的放棄第三點,我們應該為不能保障的第三點也做一些防備措施或者冗餘方案,來使系統更加的完善健全。


以上,就是對CAP定理的一些思考。