天天看點

【分布式系統工程實作】CAP理論及系統一緻性

CAP 理論由 Berkerly 的 Brewer 教授提出,三者的含義如下:

一緻性 ( Consistency) :任何一個讀操作總是能讀取到之前完成的寫操作結果;

可用性 ( Availability) :每一個操作總是能夠在确定的時間内傳回;

分區可容忍性 (Tolerance of network Partition) :在出現網絡分區的情況下,仍然能夠滿足一緻性和可用性;

CAP 理論認為,三者不能同時滿足,并給出了證明,簡單闡述如下:假設系統出現網絡分區為 G1 和 G2 兩個部分,在一個寫操作 W1 後面有一個讀操作 R2 , W1 寫 G1 , R2 讀取 G2 ,由于 G1 和 G2 不能通信,如果讀操作 R2 可以終結的話,必定不能讀取寫操作 W1 的操作結果。

由于CAP三者無法同時滿足,Amazon Dynamo論文中引入了使用者可配置的NWR政策,在CAP三個特性中作出權衡。比如N=3, W=3, R=1強調一緻性;N=3, W=1, R=1強調可用性;N=3, W=2, R=2是一種折衷的政策。另外,還有一些NOSQL系統把CAP理論當成一種借口,認為既然我們不能同時滿足一緻性和可用性,那NOSQL系統就犧牲一緻性。這些說法本身雖然不能說有錯,但我們至少需要思考兩個問題:

CAP理論在工程的角度意味着什麼?

一緻性的具體含義?

筆者認為,最初的CAP理論隻是粗略地告訴我們”天下沒有免費的午餐”,對于NOSQL系統設計指導意義不大。原始的CAP理論描述有如下缺陷:

缺少時間因素。比如對于可用性描述,10s中停服務和1個小時停服務完全是兩個概念,隻停寫服務和同時停讀寫服務的影響也是很不一樣的。

一緻性描述問題。每個讀操作雖然能夠讀取到之前寫操作結果,但是假設某些寫操作發生在機器A,某些寫操作發生在機器B,一緻性依賴于對機器A和機器B上寫操作的合并,操作的順序是無法保證的。比如Dynamo&Cassandra系統中由于可能出現同一個<key, value>對被多個節點同時修改的情形,即使在NWR政策中配置W + R > N,也需要依賴沖突合并來保證一緻性,這從理論上是沒有完美做法的。

網絡分區描述過于模糊。工程上容易出現的網絡問題一般是機房之間網絡不通,某個機房停電,某台機器故障或者某些機器因為機架電源或者交換機的原因發生故障。單個機器故障也可以認為是網絡分區,但這和機房網絡不通對系統設計帶來的挑戰差别是很大的。

一般可以認為:工程上網絡分區總是存在,比如機器故障或者網絡異常,一緻性和可用性不能同時滿足。且工程上從來不要求絕對的一緻性或者可用性,而是尋求一種平衡,可以将一緻性和可用性分别重定義為Harvest和Yield。

Harvest (對應一緻性):percent of required data actually included in the responses (請求結果的真實程度);

Yield (可用性):percent of requests answered successfully (成功請求占的百分比);

首先我們必須明确一緻性的概念。NOSQL系統經常提到最終一緻性模型:假如用戶端A寫入一個值到存儲系統,用戶端B最終總是能夠讀取到A寫入的最新值,這裡有一個時間視窗,依賴于互動延遲,系統負載以及複制技術中的replica的個數。Amazon CTO宣稱Dynamo為最終一緻性系統,然而,這裡的最終一緻性具有很大的欺騙性,因為雖然用戶端B能夠讀到其它用戶端寫入的所有資料,但是可能出現多個節點更新同一個值的情況,需要依賴沖突合并來解決多機操作順序問題。後續的文章中,我們都會把Amazon Dynamo這種需要依賴操作合并,可能會丢失資料的模型從最終一緻性模型中排除出去。最終一緻性模型要求同一份資料同一時刻隻能被一台機器修改,也就是說機器當機時需要停很短時間寫服務。

對于帶有總控節點的系統,将CAP理論的定義做出适當的調整如下:

一緻性:讀操作總是能讀取到之前完成的寫操作結果,且不需要依賴于操作合并;

可用性:讀寫操作總是能夠在很短的時間内傳回,即使某台機器發生了故障,也能夠通過其它副本正常執行,而不需要等到機器重新開機或者機器上的服務配置設定給其它機器以後才能成功;

分區可容忍性:能夠處理機器當機,機房停電或者出現機房之間網絡故障等異常情況;

帶有總控節點的NOSQL系統一般是最終一緻性系統,允許機器當機時停止很短時間,比如10s的部分資料寫服務,但是不允許停讀服務,且服務恢複時間越短越好。大多數NOSQL系統都是對一份資料保留多個備份,同一時刻隻有一個備份為主,提供寫服務,其它備份為輔,同步主備份的寫操作,所有的備份都可以提供讀取服務,且主備份提供保證強一緻性的讀服務。當主備份所在機器發生故障時,需要等一段時間才能由原來的輔備份接替主備份提供寫服務。

類似Amazon的P2P去中心化系統提供需要依賴沖突合并的一緻性,比如Cassandra中的“last write wins”沖突合并政策,雖然并不完美但确實能夠解決很多問題。這樣的系統能夠通過使用者配置NWR政策來權衡一緻性和可用性,可以做到單台機器當機時讀寫服務都不停止。

最後,再次提醒大家設計系統時:不要過分迷戀CAP,認清最終一緻性,理智對待NWR。