CAP定理 —— 一個不可能的選擇
“便宜、快速、好:選擇其中兩個”?
CAP定理:你不能同時擁有蛋糕并吃掉它。
- 一致性:蛋糕始終是同樣的口味。
- 可用性:蛋糕始終可以被吃掉。
- 分區容錯性:蛋糕可以被切成塊并共享。
CAP定理將類似的推理方法擴展到分布式系統中;具體而言,它指出分布式系統只能提供三個中的兩個理想特性:一致性、可用性和分區容錯性(CAP中的字母'C','A'和'P')。
將數據同時保存在多個節點上的網絡,無論這些節點是實際的還是虛擬的計算機,都被稱為分布式系統。
在開發云應用程序時,了解CAP定理非常重要,因為所有云應用程序都是分布式系統。
CAP的基本概念
讓我們更深入地了解CAP定理對分布式系統的三個特性的概念。
一致性
無論客戶端連接到哪個節點,它們總是同時看到相同的數據,這就是一致性。
為了實現這一點,每次將數據寫入一個節點時,必須立即將其發送或復制到系統中的所有其他節點,然后才能認為寫入已經“成功完成”。
可用性
任何請求數據的客戶端都會獲得響應,即使網絡中的一個或多個節點不可用。這就是可用性。
換句話說,分布式系統中的每個運行節點都將毫無例外地對每個請求提供合法的答案。
分區容錯性
分布式系統內部的通信中斷稱為分區。這可以被看作是系統中兩個節點之間的連接丟失或暫時延遲。
術語“分區容忍性”是指盡管在構成系統的各個節點之間的通信中出現任意數量的故障,集群的功能仍必須得到維護。
不同NoSQL數據庫的CAP原則
img
NoSQL數據庫是在分布式網絡上運行的應用程序的最佳選擇。與垂直可擴展的SQL(關系型)數據庫相比,NoSQL數據庫是水平可擴展且分布式設計的。這意味著它們能夠在由多個鏈接節點組成的發展網絡上快速擴展。
現在,NoSQL數據庫根據它們提供的兩個CAP原則進行分類,這兩個原則分別是:
CP數據庫提供一致性和分區容忍性,但以犧牲可用性為代價。如果在任意兩個節點之間發生分區,系統需要將非一致的節點停止(即使其無法訪問),直到分區問題得到解決。
AP數據庫在數據的一致性方面存在犧牲,但提供可用性和分區容忍性。當分區發生時,網絡中的所有節點仍然可訪問,但靠近分區開頭或結尾的節點可能提供比其他節點更舊的數據版本。(一旦分區問題得到解決,AP數據庫通常會重新同步節點,以糾正可能引入到系統中的任何不一致性。)
CA數據庫確保數據在系統中的所有節點之間保持一致和可訪問。然而,如果系統中的任意兩個節點之間存在分區,它無法完成這個任務,因此無法提供容錯性。
由于分區在分布式系統中是不可避免的,我們故意將CA數據庫類型放在列表的最后。因此,雖然可以在理論上討論CA分布式數據庫的概念,但實際上,這樣的數據庫根本不存在。然而,如果你覺得你的分布式應用需要CA數據庫,并不意味著你不能擁有這樣一個數據庫。
包括PostgreSQL在內的各種關系型數據庫都可以提供一致性和可用性,并可以在多個節點上進行復制以進行分布式部署。
CAP定理和MongoDB
MongoDB將數據存儲為BSON(二進制JSON)文檔,使其成為常見的NoSQL數據庫管理系統。它廣泛用于大規模、實時、分布式應用。
MongoDB是一個CP數據存儲,因為它能夠在保持數據一致性的同時解決網絡分區問題,但以犧牲可用性為代價,正如CAP定理所描述的那樣。
在MongoDB中,一個復制集(replica set)只能有一個主節點來處理所有寫操作。復制集中的次要節點復制主節點的事務日志,并使用它來更新自己的數據副本。客戶端默認從主節點讀取數據,但可以通過設置讀偏好來更改這一行為。
如果原始節點故障,最近操作日志最多的次要節點將被提升為主節點。只要所有從節點都趕上了新的主節點,集群就會恢復可訪問性。在此期間,沒有客戶端可以發送寫請求,因此數據在整個網絡上是同步的。
CAP定理(AP)和Cassandra
Apache軟件基金會開發和分發Cassandra,這是一個自由開源的NoSQL數據庫。它以寬列數據庫的形式進行分布式數據存儲。由于其無主節點的設計,Cassandra沒有像MongoDB那樣的單點故障。
Cassandra是一個AP數據庫,因為它滿足了一些但不是所有的一致性、可用性和分區容忍性(CAP)要求。由于缺乏主節點,Cassandra集群中的所有節點始終處于運行狀態至關重要。另一方面,Cassandra通過允許客戶端隨時向任何節點寫入數據并迅速解決不一致性問題來提供最終一致性。
Cassandra具有“修復”功能,以幫助節點趕上其對等節點,因為只有在網絡分裂的情況下數據才會變得不一致,并且不一致性會迅速得到糾正。然而,持續的可用性會產生高性能的系統,在某些情況下可能值得付出代價。
結論
如果你正在創建基于微服務的分布式項目,了解CAP定理可以幫助你選擇合適的數據庫。例如,如果你可以接受最終一致性(而不是嚴格一致性),但需要快速迭代數據模型并進行水平擴展,那么像Cassandra或Apache CouchDB這樣的AP數據庫可能能滿足你的需求并簡化部署。
另一方面,如果你的應用程序的成功取決于數據的可靠性,例如電子商務或支付服務,那么關系型數據庫如PostgreSQL可能是最佳選擇。