CAP原則介紹
CAP原則又稱CAP定理,指的是在一個分布式系統中,一致性(Consistency)、可用性(Availability)、分區容錯性(Partition tolerance)。CAP 原則指的是,這三個要素最多只能同時實現兩點,不可能三者兼顧。
CAP的三個指標
一致性(Consistency)
“all nodes see the same data at the same time”,即更新操作成功並返回客戶端后,所有節點在同一時間的數據完全一致,這就是分布式的一致性。一致性的問題在並發系統中不可避免,對於客戶端來說,一致性指的是並發訪問時更新過的數據如何獲取的問題。從服務端來看,則是更新如何復制分布到整個系統,以保證數據最終一致
可用性(Availability)
可用性指“Reads and writes always succeed”,即服務一直可用,而且是正常響應時間。好的可用性主要是指系統能夠很好的為用戶服務,不出現用戶操作失敗或者訪問超時等用戶體驗不好的情況。
分區容錯性(Partition tolerance)
即分布式系統在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一致性或可用性的服務。
CAP定理的證明
以下說明為什么CAP 原則三個要素最多只能同時實現兩點,不可能三者兼顧。
假設有一個客戶端C用戶A,2台服務器,分別部署了2個同樣的服務節點S1、S2,存放的數據都是V0,他們之間的網絡可以互通,也就相當於分布式系統的兩個部分。
操作流程
1、客戶端A更新了數據V1到S1
2、S1節點這個消息告訴S2節點,想讓S2頁更新數據,卻發生了網絡故障,S2中保存的還是V0
3、客戶端向S2請求數據,S2返回V0數據
分析
(1)系統網絡發生了故障,但是系統依然可以訪問,因此具有容錯性。
(2)客戶端A訪問節點S1的時候更改了V0到V1,想要客戶端A訪問節點S2的時候是V1,因此需要等網絡故障恢復,將S2節點的數據進行更新才可以。
(3)在網絡故障恢復的這段時間內,想要系統滿足可用性,是不可能的。因為可用性要求隨時隨地訪問系統都是正確有效的。這就出現了矛盾。
正是這個矛盾所以CAP三個特性肯定不能同時滿足。既然不能滿足,那我們就進行取舍。
有二種選擇:
第一,犧牲數據一致性,響應舊的數據V0給客戶端;
第二,犧牲可用性,阻塞等待,直到網絡連接恢復,數據更新操作完成之后,再給用戶響應最新的數據V1。
取舍策略
CA without P:如果不要求P(不允許分區),則C(強一致性)和A(可用性)是可以保證的。但放棄P的同時也就意味着放棄了系統的擴展性,也就是分布式節點受限,沒辦法部署子節點,這是違背分布式系統設計的初衷的。
CP without A:如果不要求A(可用),相當於每個請求都需要在服務器之間保持強一致,而P(分區)會導致同步時間無限延長(也就是等待數據同步完才能正常訪問服務),一旦發生網絡故障或者消息丟失等情況,就要犧牲用戶的體驗,等待所有數據全部一致了之后再讓用戶訪問系統。設計成CP的系統其實不少,最典型的就是分布式數據庫,如Redis、HBase等。對於這些分布式數據庫來說,數據的一致性是最基本的要求,因為如果連這個標准都達不到,那么直接采用關系型數據庫就好,沒必要再浪費資源來部署分布式數據庫。
AP wihtout C:要高可用並允許分區,則需放棄一致性。一旦分區發生,節點之間可能會失去聯系,為了高可用,每個節點只能用本地數據提供服務,而這樣會導致全局數據的不一致性。典型的應用就如某米的搶購手機場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品准備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統可以正常的服務,然后在數據的一致性方面做了些犧牲,雖然多少會影響一些用戶體驗,但也不至於造成用戶購物流程的嚴重阻塞。
一般來說,分區容錯無法避免,因此可以認為 CAP 的 P 總是成立。CAP 定理告訴我們,剩下的 C 和 A 無法同時做到。