ACID中C與CAP定理中C的區別
ACID和CAP定理中都有C,代表Consistent一致性,很多人容易將這兩個C混為一談,其實這兩個一致性是有區別的。
事務的定義是一系列操作要麼全部成功,要麼全部不成功,資料庫的事務機制是通過ACID實現的,資料庫ACID的具體定義見這裡,ACID中的一致性的定義是:一個事務可以封裝狀態改變(除非它是一個只讀的)。事務必須始終保持系統處於一致的狀態,不管在任何給定的時間併發事務有多少。
也就是說:如果事務是併發多個,系統也必須如同序列事務一樣操作。其主要特徵是保護性和不變性(Preserving an Invariant),以轉賬案例為例,假設有五個賬戶,每個賬戶餘額是100元,那麼五個賬戶總額是500元,如果在這個5個賬戶之間同時發生多個轉賬,無論併發多少個,比如在A與B賬戶之間轉賬5元,在C與D賬戶之間轉賬10元,在B與E之間轉賬15元,五個賬戶總額也應該還是500元,這就是保護性和不變性。
如果說ACID的C是節點伺服器的資料完整性,而CAP的一致性是分散式多伺服器之間複製資料以取得這些伺服器擁有同樣的資料,這是一種分散式領域的一致性概念。因此兩者是完全不同的概念。
分散式領域中的一致性有的強弱之分,強一致性也就是指一旦有寫操作寫入任何一個伺服器,立即在其他伺服器之間同步複製新的資料,這樣, 任何伺服器上任何讀操作總是能看到最近寫入的新資料。如果不能立即看到最近寫入的新資料,而可能過了一段時間才能看到,則屬於弱一致性或最終一致性了。
強一致性分為由寫實現一致性Consistency by writes、由讀實現一致性Consistency by reads和由衝裁實現一致性Consistency by Quorum。
由寫實現一致性:在寫入資料同時,將資料複製到其他伺服器上,讀取任何一臺都可以獲得新的寫入資料,複製資料是在寫操作完成,讀操作輕量。
由讀實現一致性:寫入一旦伺服器後,不再複製,而是在讀取時使用版本來協調複製(如vector clock演算法),這樣我們簡化了寫操作,而將負擔加在讀操作。
由衝裁實現一致性:如果寫入時複製到其他2/3大多數伺服器,讀取時也是從2/3大多數伺服器讀取,讀取這邊負責解決哪個更新是最新結果,這在讀操作和寫操作之間分擔了負載。
回到事務話題,如果要在分散式系統中實現像ACID那樣的事務機制,只有強一致性還是不夠的,如果我們操作步驟順序很重要,不可以中斷或打亂,我們要麼一起一次執行它們,如果併發執行這些操作步驟,無論怎麼併發,也要如同它們是在獨立執行,我們最終得到的結果總是相同的,這是一種更強的一致性:線性一致性linearizable consistency,類似ACID中的隔離層(serial isolation level)。
The CAP FAQ將CAP定理中的一致性定義為這種線性一致性或稱為atomic原子一致性。一種比普通一致性更強的一致性,這也是大家又將ACID的C和CAP的C等同在一起的原因。ACID的C與CAP的C的關係類似精確與一致性的關係,如下圖:
這種分散式的線性強一致性有兩種實現方式:2PC兩段提交和Paxos演算法是常見兩種。
通過2PC寫入新資料需要經過兩次來回,第一次請求commit,第二次才正式確認commit,在這兩者之間過程中,所有伺服器都會堵塞等待發起者發出整個事務成功還是失敗的結果(只有發起者知道所有伺服器的情況),如果失敗,所有伺服器返回之前狀態,相當於寫入資料失敗,寫入資料沒有發生過一樣。
而Paxos演算法能夠迴避2PC的堵塞死鎖等問題更好地實現伺服器之間資料強一致複製,具體內容見:Paxos演算法。也可參考比Paxos演算法改進的Raft演算法。
參考:
Lightweight transactions in Cassandra 2.0
Distributed algorithms and protocols:Consistency
[該貼被banq於2015-01-02 20:00修改過]
相關文章
- C與C++中struct使用的區別C++Struct
- C#中List與IList的區別C#
- C/C++——C++中new與malloc的10點區別C++
- 引用的例子 C C++ 中區別C++
- 分散式系統中的CAP、ACID、BASE概念分散式
- C++基礎::STL中的定理C++
- C++中結構體與類的區別C++結構體
- C++中new與malloc的10點區別C++
- 關於事務的ACID屬性中的“C”與“I”
- c與c++的區別C++
- C#中Hashtable和HashMap的區別C#HashMap
- C++中的return和exit區別C++
- C++中 struct 和 class 的區別C++Struct
- C++中struct 和 class的區別C++Struct
- C#中ref和out的區別C#
- c#中Array,ArrayList 與List<T>的區別、共性與轉換C#
- 關於C與C++的區別C++
- const關鍵字在C與C++中修飾變數的區別C++變數
- CAP定理的缺點
- C++中運算子 &和&&、|和|| 的區別C++
- 【轉】C#中virtual和abstract的區別C#
- C#中堆和堆疊的區別C#
- C++中L和_T()之區別C++
- c++中&和&&有什麼區別C++
- .net與C#的區別C#
- JAVA 與 C++ 的區別JavaC++
- c#與java的區別C#Java
- IL角度理解C#中欄位,屬性與方法的區別C#
- C#中抽象方法與虛方法的區別詳解及示例C#抽象
- C# 中List中的Count和Count(),有什麼區別C#
- C# 中 Struct 和 Class 的區別總結C#Struct
- C# 中的 == 和 equals()有什麼區別?C#
- c++中的變數型別_C ++中的變數C++變數型別
- CAP定理在分散式系統設計中的最新應用分散式
- C#中的屬性和欄位的區別C#
- C#中String和string區別C#
- [C#]C#中ToString()和Convert.ToString()的區別C#
- Java與C語言的區別?JavaC語言