1.CAP概述
CAP理論是由EricBrewer教授提出的,在設計和部署分布式應用的時候,存在三個核心的系統需求,這個三個需求之間存在一定的特殊關係。三個需求如下:
C: Consistency 一致性
A: Availability 可用性
P:Partition Tolerance分區容錯性
CAP理論的核心是:一個分布式系統不可能同時很好的滿足一致性,可用性和分區容錯性這三個需求,最多隻能同時較好的滿足兩個。
2.CAP定義
(1)C: Consistency 一致性
一致性又稱為原子性或者事務性。表示一個事務的操作是不可分割的,要不然這個事務完成,要不然這個事務不完成,不會出現這個事務完成了一半這樣的情況。這種事務的原子性使得資料具有一致性。
我們通常情況下在資料庫中存在的髒資料就屬於資料沒有具有一致性的表現。而在分布式系統中,經常出現的一個資料不具有一致性的情況是讀寫資料時缺乏一致性。比如兩個節點資料冗餘,第一個節點有一個寫操作,資料更新以後沒有有效使得第二個節點更新資料,在讀取第二個節點的時候就會出現不一致的問題出現。
傳統的ACID資料庫是很少存在一致性問題的,因為資料的單點原因,資料的存取又具有良好的事務性,不會出現讀寫的不一致。
(2)A: Availability 可用性
好的可用性主要是指系統能夠很好的為使用者服務,不出現使用者操作失敗或者訪問逾時等使用者體驗不好的情況。可用性通常情況下可用性和分布式資料冗餘,負載平衡等有著很大的關聯。
(3)P:Partition Tolerance分區容錯性
分區容錯性和擴充性緊密相關。在分布式應用中,可能因為一些分布式的原因導致系統無法正常運轉。好的分區容錯性要求能夠使應用雖然是一個分布式系統,而看上去卻好像是在一個可以運轉正常的整體。比如現在的分布式系統中有某一個或者幾個機器宕掉了,其他剩下的機器還能夠正常運轉滿足系統需求,這樣就具有好的分區容錯性。
3.CAP理論的意義
隨著互連網應用的飛速發展,資料量與日俱增,傳統的ACID資料庫已經不能滿足如此大的海量資料存放區了。這個時候需要設計出好的分布式資料存放區方式。而這些分布式資料存放區方式受到CAP理論的約束,不可能達到高一致性,高可用性,高分區容錯性的完美設計。所以我們在設計的時候要懂得取捨,重點關注對應用需求來說比較重要的,而放棄不重要的,在CAP這三者之間進行取捨,設計出貼合應用的儲存方案。
目前眾多的分布式資料系統通過降低一致性來換取可用性。下面是一個簡單的例子:
兩個節點資料冗餘,第一個節點先有一個寫操作,第二個節點後有一個讀操作。下面的圖中a是整個過程,要具有一致性的話需要等待a1進行write,然後同步到a2,然後a2再進行write,只有整個事務完成以後,a2才能夠進行read。但是這樣的話使得整個系統的可用性下降,a2一直阻塞在那裡等待a1同步到a2。這個時候如果對一致性要求不高的話,a2可以不等待a1資料對於a2的寫同步,直接讀取,這樣雖然此時的讀寫不具有一致性,但是在後面可以通過非同步方式使得a1和a2的資料最終一致,達到最終一致性。
4.BASE理論
BASE理論是CAP理論結合實際的產物。 BASE(Basically Available, Soft-state,Eventuallyconsistent)英文中有堿的意思,這個正好和ACID的酸的意義相對,很有意思。BASE恰好和ACID是相對的,BASE要求犧牲高一致性,獲得可用性或可靠性。
5.CAP之間的取捨
滿足一致性,可用性的系統,通常在可擴充性上不太強大:
· Traditional RDBMSs like Postgres,MySQL, etc (relational)
· Vertica (column-oriented)
· Aster Data (relational)
· Greenplum (relational)
滿足一致性,分區容忍必的系統,通常效能不是特別高:
· BigTable (column-oriented/tabular)
· Hypertable (column-oriented/tabular)
· HBase (column-oriented/tabular)
· MongoDB (document-oriented)
· Terrastore (document-oriented)
· Redis (key-value)
· Scalaris (key-value)
· MemcacheDB (key-value)
· Berkeley DB (key-value)
滿足可用性,分區容忍性的系統,通常可能對一致性要求低一些:
· Dynamo (key-value)
· Voldemort (key-value)
· Tokyo Cabinet (key-value)
· KAI (key-value)
· Cassandra (column-oriented/tabular)
· CouchDB (document-oriented)
· SimpleDB (document-oriented)
· Riak (document-oriented)
6.CAP的反對聲音
Guy Pardon寫了一篇文章“A CAP Solution (Proving Brewer Wrong)”來反對CAP理論。他提出了一個同時滿足CAP的解決方案來反對Brewer的三者只能取其二的說法。
他設計的系統如下:
(1)程式如果能夠讀取資料庫的話讀取資料庫,如果不能的話可以使用緩衝代替。
(2)所有的讀取操作使用版本號碼或者其他可以使用樂觀鎖的機制。
(3)用戶端的所有更新操作全部放在隊列中順序處理。更新操作中要包括該更新的讀取操作時的版本資訊。
(4)當分區數量足夠少的時候,可以處理隊列中的更新操作。比較簡單的方式是建立一個跨越所有分布式副本的事務,對每個副本進行更新操作(其他方式比如quorum等等也可以)。如果該更新的讀取操作時的版本資訊不是當前資料庫中資料的版本資訊,則將失敗返回給用戶端,否則返回成功。
(5)資料庫操作結果(確認或者取消)通過非同步方式發送到用戶端,可以通過郵件,訊息佇列或者其他非同步方式。
該系統符合CAP如下:
符合C(高一致性):讀取的資料都是基於快照的,而且錯誤的更新操作不會執行。
符合A(高可用性):讀取和更新都會返回資料。
符合P(高分區容錯性):允許網路或者節點出錯。
該設計是符合BASE理論的。
參考資料:
http://www.julianbrowne.com/article/viewer/brewers-cap-theorem
http://www.sigma.me/2011/06/13/NoSQL-CAP-Theorem.html
http://blog.nosqlfan.com/html/1112.html
http://guysblogspot.blogspot.com/2008/09/cap-solution-proving-brewer-wrong.html