NoSQL學習筆記(二)之CAP理論

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(BasicallyAvailable,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