分佈式CAP理論


分佈式CAP理論

來自wiki:php

理論計算機科學中,CAP定理(CAP theorem),又被稱做布魯爾定理(Brewer's theorem),它指出對於一個分佈式計算系統來講,不可能同時知足如下三點:[1][2]html

  • 一致性(Consistency) (等同於全部節點訪問同一份最新的數據副本)
  • 可用性Availability)(每次請求都能獲取到非錯的響應——可是不保證獲取的數據爲最新數據)
  • 分區容錯性Partition tolerance)(以實際效果而言,分區至關於對通訊的時限要求。系統若是不能在時限內達成數據一致性,就意味着發生了分區的狀況,必須就當前操做在C和A之間作出選擇[3]。)

根據定理,分佈式系統只能知足三項中的兩項而不可能知足所有三項[4]。理解CAP理論的最簡單方式是想象兩個節點分處分區兩側。容許至少一個節點更新狀態會致使數據不一致,即喪失了C性質。若是爲了保證數據一致性,將分區一側的節點設置爲不可用,那麼又喪失了A性質。除非兩個節點能夠互相通訊,才能既保證C又保證A,這又會致使喪失P性質。node

來自:數據庫

HollisChuang's Blog-Java乾貨集散地

2000年7月,加州大學伯克利分校的Eric Brewer教授在ACM PODC會議上提出CAP猜測。2年後,麻省理工學院的Seth Gilbert和Nancy Lynch從理論上證實了CAP。以後,CAP理論正式成爲分佈式計算領域的公認定理。安全

不管你是一個系統架構師,仍是一個普通開發,當你開發或者設計一個分佈式系統的時候,CAP理論是不管如何也繞不過去的。本文就來介紹一下到底什麼是CAP理論,如何證實CAP理論,以及CAP的權衡問題。服務器

CAP理論概述

CAP理論:一個分佈式系統最多隻能同時知足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。網絡

Teorema-CAP-2

讀者須要注意的的是,CAP理論中的CA和數據庫事務中ACID的CA並徹底是同一回事兒。二者之中的A都是C都是一致性(Consistency)。CAP中的A指的是可用性(Availability),而ACID中的A指的是原子性(Atomicity),切勿混爲一談。架構

CAP的定義

Consistency 一致性

一致性指「all nodes see the same data at the same time」,即更新操做成功並返回客戶端完成後,全部節點在同一時間的數據徹底一致,因此,一致性,說的就是數據一致性。分佈式的一致性併發

對於一致性,能夠分爲從客戶端和服務端兩個不一樣的視角。從客戶端來看,一致性主要指的是多併發訪問時更新過的數據如何獲取的問題。從服務端來看,則是更新如何複製分佈到整個系統,以保證數據最終一致。負載均衡

一致性是由於有併發讀寫纔有的問題,所以在理解一致性的問題時,必定要注意結合考慮併發讀寫的場景。

從客戶端角度,多進程併發訪問時,更新過的數據在不一樣進程如何獲取的不一樣策略,決定了不一樣的一致性。

三種一致性策略

對於關係型數據庫,要求更新過的數據能被後續的訪問都能看到,這是強一致性。

若是能容忍後續的部分或者所有訪問不到,則是弱一致性。

若是通過一段時間後要求能訪問到更新後的數據,則是最終一致性。

CAP中說,不可能同時知足的這個一致性指的是強一致性。

Availability 可用性

可用性指「Reads and writes always succeed」,即服務一直可用,並且是正常響應時間。

對於一個可用性的分佈式系統,每個非故障的節點必須對每個請求做出響應。因此,通常咱們在衡量一個系統的可用性的時候,都是經過停機時間來計算的。

可用性分類 可用水平(%) 年可容忍停機時間
容錯可用性 99.9999 <1 min
極高可用性 99.999 <5 min
具備故障自動恢復能力的可用性 99.99 <53 min
高可用性 99.9 <8.8h
商品可用性 99 <43.8 min

一般咱們描述一個系統的可用性時,咱們說淘寶的系統可用性能夠達到5個9,意思就是說他的可用水平是99.999%,即整年停機時間不超過 (1-0.99999)*365*24*60 = 5.256 min,這是一個極高的要求。

好的可用性主要是指系統可以很好的爲用戶服務,不出現用戶操做失敗或者訪問超時等用戶體驗很差的狀況。一個分佈式系統,上下游設計不少系統如負載均衡、WEB服務器、應用代碼、數據庫服務器等,任何一個節點的不穩定均可以影響可用性。

Partition Tolerance分區容錯性

分區容錯性指「the system continues to operate despite arbitrary message loss or failure of part of the system」,即分佈式系統在遇到某節點或網絡分區故障的時候,仍然可以對外提供知足一致性和可用性的服務。

分區容錯性和擴展性緊密相關。在分佈式應用中,可能由於一些分佈式的緣由致使系統沒法正常運轉。好的分區容錯性要求可以使應用雖然是一個分佈式系統,而看上去卻好像是在一個能夠運轉正常的總體。好比如今的分佈式系統中有某一個或者幾個機器宕掉了,其餘剩下的機器還可以正常運轉知足系統需求,或者是機器之間有網絡異常,將分佈式系統分隔未獨立的幾個部分,各個部分還能維持分佈式系統的運做,這樣就具備好的分區容錯性。

簡單點說,就是在網絡中斷,消息丟失的狀況下,系統若是還能正常工做,就是有比較好的分區容錯性。

CAP的證實

intro_thumb

如上圖,是咱們證實CAP的基本場景,網絡中有兩個節點N1和N2,能夠簡單的理解N1和N2分別是兩臺計算機,他們之間網絡能夠連通,N1中有一個應用程序A,和一個數據庫V,N2也有一個應用程序B2和一個數據庫V。如今,A和B是分佈式系統的兩個部分,V是分佈式系統的數據存儲的兩個子數據庫。

在知足一致性的時候,N1和N2中的數據是同樣的,V0=V0。在知足可用性的時候,用戶無論是請求N1或者N2,都會獲得當即響應。在知足分區容錯性的狀況下,N1和N2有任何一方宕機,或者網絡不通的時候,都不會影響N1和N2彼此之間的正常運做。

scenario1_thumb

如上圖,是分佈式系統正常運轉的流程,用戶向N1機器請求數據更新,程序A更新數據庫Vo爲V1,分佈式系統將數據進行同步操做M,將V1同步的N2中V0,使得N2中的數據V0也更新爲V1,N2中的數據再響應N2的請求。

這裏,能夠定義N1和N2的數據庫V之間的數據是否同樣爲一致性;外部對N1和N2的請求響應爲可用行;N1和N2之間的網絡環境爲分區容錯性。這是正常運做的場景,也是理想的場景,然而現實是殘酷的,當錯誤發生的時候,一致性和可用性還有分區容錯性,是否能同時知足,仍是說要進行取捨呢?

做爲一個分佈式系統,它和單機系統的最大區別,就在於網絡,如今假設一種極端狀況,N1和N2之間的網絡斷開了,咱們要支持這種網絡異常,至關於要知足分區容錯性,能不能同時知足一致性和響應性呢?仍是說要對他們進行取捨。

scenario2_thumb

假設在N1和N2之間網絡斷開的時候,有用戶向N1發送數據更新請求,那N1中的數據V0將被更新爲V1,因爲網絡是斷開的,因此分佈式系統同步操做M,因此N2中的數據依舊是V0;這個時候,有用戶向N2發送數據讀取請求,因爲數據尚未進行同步,應用程序沒辦法當即給用戶返回最新的數據V1,怎麼辦呢?

有二種選擇,第一,犧牲數據一致性,保證可用性。響應舊的數據V0給用戶;

第二,犧牲可用性,保證數據一致性。阻塞等待,直到網絡鏈接恢復,數據更新操做M完成以後,再給用戶響應最新的數據V1。

這個過程,證實了要知足分區容錯性的分佈式系統,只能在一致性和可用性二者中,選擇其中一個。

CAP權衡

經過CAP理論及前面的證實,咱們知道沒法同時知足一致性、可用性和分區容錯性這三個特性,那要捨棄哪一個呢?

咱們分三種狀況來闡述一下。

CA without P

這種狀況在分佈式系統中幾乎是不存在的。首先在分佈式環境下,網絡分區是一個天然的事實。由於分區是必然的,因此若是捨棄P,意味着要捨棄分佈式系統。那也就沒有必要再討論CAP理論了。這也是爲何在前面的CAP證實中,咱們以系統知足P爲前提論述了沒法同時知足C和A。

好比咱們熟知的關係型數據庫,如My Sql和Oracle就是保證了可用性和數據一致性,可是他並非個分佈式系統。一旦關係型數據庫要考慮主備同步、集羣部署等就必需要把P也考慮進來。

其實,在CAP理論中。C,A,P三者並非平等的,CAP之父在《Spanner,真時,CAP理論》一文中寫到:

若是說Spanner真有什麼特別之處,那就是谷歌的廣域網。Google經過創建私有網絡以及強大的網絡工程能力來保證P,在多年運營改進的基礎上,在生產環境中能夠最大程度的減小分區發生,從而實現高可用性。

從Google的經驗中能夠獲得的結論是,沒法經過下降CA來提高P。要想提高系統的分區容錯性,須要經過提高基礎設施的穩定性來保障。

因此,對於一個分佈式系統來講。P是一個基本要求,CAP三者中,只能在CA二者之間作權衡,而且要想盡辦法提高P。

CP without A

若是一個分佈式系統不要求強的可用性,即允許系統停機或者長時間無響應的話,就能夠在CAP三者中保障CP而捨棄A。

一個保證了CP而一個捨棄了A的分佈式系統,一旦發生網絡故障或者消息丟失等狀況,就要犧牲用戶的體驗,等待全部數據所有一致了以後再讓用戶訪問系統。

設計成CP的系統其實也很多,其中最典型的就是不少分佈式數據庫,他們都是設計成CP的。在發生極端狀況時,優先保證數據的強一致性,代價就是捨棄系統的可用性。如Redis、HBase等,還有分佈式系統中經常使用的Zookeeper也是在CAP三者之中選擇優先保證CP的。

不管是像Redis、HBase這種分佈式存儲系統,仍是像Zookeeper這種分佈式協調組件。數據的一致性是他們最最基本的要求。一個連數據一致性都保證不了的分佈式存儲要他有何用?

在個人Zookeeper介紹(二)——Zookeeper概述一文中其實介紹過zk關於CAP的思考,這裏再簡單回顧一下:

ZooKeeper是個CP(一致性+分區容錯性)的,即任什麼時候刻對ZooKeeper的訪問請求能獲得一致的數據結果,同時系統對網絡分割具有容錯性。可是它不能保證每次服務請求的可用性,也就是在極端環境下,ZooKeeper可能會丟棄一些請求,消費者程序須要從新請求才能得到結果。ZooKeeper是分佈式協調服務,它的職責是保證數據在其管轄下的全部服務之間保持同步、一致。因此就不難理解爲何ZooKeeper被設計成CP而不是AP特性的了。

AP wihtout C

要高可用並容許分區,則需放棄一致性。一旦網絡問題發生,節點之間可能會失去聯繫。爲了保證高可用,須要在用戶訪問時能夠立刻獲得返回,則每一個節點只能用本地數據提供服務,而這樣會致使全局數據的不一致性。

這種捨棄強一致性而保證系統的分區容錯性和可用性的場景和案例很是多。前面咱們介紹可用性的時候說到過,不少系統在可用性方面會作不少事情來保證系統的整年可用性能夠達到N個9,因此,對於不少業務系統來講,好比淘寶的購物,12306的買票。都是在可用性和一致性之間捨棄了一致性而選擇可用性。

你在12306買票的時候確定遇到過這種場景,當你購買的時候提示你是有票的(可是可能實際已經沒票了),你也正常的去輸入驗證碼,下單了。可是過了一會系統提示你下單失敗,餘票不足。這其實就是先在可用性方面保證系統能夠正常的服務,而後在數據的一致性方面作了些犧牲,會影響一些用戶體驗,可是也不至於形成用戶流程的嚴重阻塞。

可是,咱們說不少網站犧牲了一致性,選擇了可用性,這其實也不許確的。就好比上面的買票的例子,其實捨棄的只是強一致性。退而求其次保證了最終一致性。也就是說,雖然下單的瞬間,關於車票的庫存可能存在數據不一致的狀況,可是過了一段時間,仍是要保證最終一致性的。

對於多數大型互聯網應用的場景,主機衆多、部署分散,並且如今的集羣規模愈來愈大,因此節點故障、網絡故障是常態,並且要保證服務可用性達到N個9,即保證P和A,捨棄C(退而求其次保證最終一致性)。雖然某些地方會影響客戶體驗,但沒達到形成用戶流程的嚴重程度。

適合的纔是最好的

上面介紹瞭如何CAP中權衡及取捨以及典型的案例。孰優孰略,沒有定論,只能根據場景定奪,適合的纔是最好的。

對於涉及到錢財這樣不能有一絲讓步的場景,C必須保證。網絡發生故障寧肯中止服務,這是保證CP,捨棄A。好比前幾年支付寶光纜被挖斷的事件,在網絡出現故障的時候,支付寶就在可用性和數據一致性之間選擇了數據一致性,用戶感覺到的是支付寶系統長時間宕機,可是其實背後是無數的工程師在恢復數據,保證數數據的一致性。

對於其餘場景,比較廣泛的作法是選擇可用性和分區容錯性,捨棄強一致性,退而求其次使用最終一致性來保證數據的安全。這實際上是分佈式領域的另一個理論——BASE理論。咱們下一篇文章再來介紹。

總結

不管你是一個架構師,仍是一個普通開發,在設計或開發分佈式系統的時候,不可避免的要在CAP中作權衡。須要根據本身的系統的實際狀況,選擇最適合本身的方案。

參考資料:

CAP和BASE理論

CAP原理的證實

一文帶你從新審視CAP理論與分佈式系統設計

拓展閱讀:

CAP理論

相關文章
相關標籤/搜索