CAP是全部分佈式系統的基礎理論,任何分佈式系統只能知足如下三種狀態中的任意兩種。node
CAP理論是指一個分佈式系統不能同時知足一致性、可用性和分區容錯性。聽起來簡單,但一致性、可用性和分區容錯性分別是指啥?甚至分佈式系統是啥?git
在這篇文章中,咱們會引入一個簡單的分佈式系統來解釋清楚何爲可用性、一致性、和分區容錯性。更多信息能夠參考Gilbert和Lynch的論文Perspectives on the CAP Theorem。github
假設咱們有這樣一個簡單的分佈式系統,它包含兩個服務G1和G2,這倆服務都保存着同一變量v,其初始值是v0。 G1和G2之間能夠互相溝通,同時他們也能夠和其餘的客戶端溝通,以下圖所示:
網絡
客戶端能夠讀取和修改任意一個服務端的值。當服務端收到請求,他會作相應處理後回覆客戶端。若是是寫請求執行過程以下圖所示:
分佈式
若是是讀請求,執行過程以下圖:
.net
如今咱們已經創建了一個簡單的分佈式系統,接下來咱們分別看下一致性、可用性和分區容錯性。blog
Gilbert和Lynch的論文中是這樣描述一致性的:圖片
any read operation that begins after a write operation completes must return that value, or the result of a later write operation
在某個寫操做完成以後的任何讀操做都必須返回該寫操做寫入的值,或者再以後的寫操做寫入的值。rem
在一個一致性的系統中,若是一個客戶端寫入了某個值到任意一個服務端上,而且獲得了服務端的確認,那麼客戶端再去讀的時候,無論是讀的哪一個服務,都指望拿到寫入後的值或者是更新的值。get
下圖所示是有個不保證一致性的系統:
客戶端向G1發送了寫請求將v的值從v0變動到v1,而後也獲得了G1的寫入成功確認,但從G2讀到的數據仍是舊的數據v0。
下圖是一個保證一致性的系統:
在這個系統中,當客戶端向G1寫入數據v1後,G1也會把數據同步到G2,當G1 G2都完成數據更新後,G1纔會告訴客戶端寫入成功。 以後不過是客戶端從G1讀仍是從G2讀,讀到的都是最新的值v1。
Gilbert和Lynch的論文對可用性的描述以下:
every request received by a non-failing node in the system must result in a response
任何一個在線的節點收到的請求必須都作出相應。
在保證可用性的系統中,若是客戶端向某個沒有宕機的服務端發送了請求,服務端必須響應客戶端的請求,不能選擇忽略掉客戶端的請求。
Gilbert和Lynch的論文對分區容錯性的描述以下:
the network will be allowed to lose arbitrarily many messages sent from one node to another
容許網絡丟失從一個服務節點到另一個服務節點的任意信息
這就意味着在咱們的分佈式系統中,G1發送給G2的信息可能會丟失,若是全部的信息都丟失了,咱們的系統可能就會變成這樣。
爲了保證分區容錯性,咱們的系統必須在任意個不通的網絡分區下正常工做。
如今咱們已經瞭解了什麼是一致性、可用性和分區容錯性,接下來咱們證實下爲何一個分佈式系統不能同時知足這三者。
假設存在一個同時知足一致性、可用性和分區容錯性的分佈式系統。首先咱們把這個系統分紅兩個部分,以下圖:
接下來客戶端將G1中的v從v0改爲v1,由於要知足可用性的要求,G1必須響應客戶端的寫入請求,可是由於網絡的問題,G1無法將數據同步到G2。Gilbert和Lynch將這個階段稱爲alpha1階段,以下圖:
再而後,假設有個客戶端從G2讀了v的值,由於知足可用性要求,G2也必須正常響應,由於網絡的問題,G2沒有更新到G1的數據,因此G2只能返回v0,Gilbert和Lynch將這個階段稱爲alpha2階段,以下圖:
在這裏G1返回v1,G2只能返回v1,產生了不一致,和咱們的假設相悖,因此證實同時知足一致性、可用性和分區容錯性的分佈式系統不存在。
https://mwhittaker.github.io/blog/an_illustrated_proof_of_the_cap_theorem/