理論的優(yōu)點在于清晰簡潔、易于理解,但缺點就是高度抽象化,省略了很多細節(jié),導致在將理論應用到實踐時,由于各種復雜情況,可能出現(xiàn)誤解和偏差,CAP 理論也不例外。如果我們沒有意識到這些關鍵的細節(jié)點,那么在實踐中應用 CAP 理論時,就可能發(fā)現(xiàn)方案很難落地。
而且當談到數(shù)據(jù)一致性時,CAP、ACID、BASE 難免會被我們拿出來討論,原因在于這三者都是和數(shù)據(jù)一致性相關的理論,如果不仔細理解三者之間的差別,則可能會陷入一頭霧水的狀態(tài),不知道應該用哪個才好。
今天,我來講講 CAP 的具體細節(jié),簡單對比一下 ACID、BASE 幾個概念的關鍵區(qū)別點。
CAP關鍵細節(jié)點
埃里克·布魯爾闡述了理解和應用 CAP 的一些細節(jié)點,可能是由于作者寫作風格的原因,對于一些非常關鍵的細節(jié)點一句話就帶過了,這里我特別提煉出來重點闡述。CAP 關注的粒度是數(shù)據(jù),而不是整個系統(tǒng)。原文就只有一句話:
C 與 A 之間的取舍可以在同一系統(tǒng)內(nèi)以非常細小的粒度反復發(fā)生,而每一次的決策可能因為具體的操作,乃至因為牽涉到特定的數(shù)據(jù)或用戶而有所不同。
但這句話是理解和應用 CAP 理論非常關鍵的一點。CAP 理論的定義和解釋中,用的都是 system、node 這類系統(tǒng)級的概念,這就給很多人造成了很大的誤導,認為我們在進行架構設計時,整個系統(tǒng)要么選擇 CP,要么選擇 AP。
但在實際設計過程中,每個系統(tǒng)不可能只處理一種數(shù)據(jù),而是包含多種類型的數(shù)據(jù),有的數(shù)據(jù)必須選擇 CP,有的數(shù)據(jù)必須選擇 AP。而如果我們做設計時,從整個系統(tǒng)的角度去選擇 CP 還是 AP,就會發(fā)現(xiàn)顧此失彼,無論怎么做都是有問題的。
CAP 是忽略網(wǎng)絡延遲的
這是一個非常隱含的假設,布魯爾在定義一致性時,并沒有將延遲考慮進去。也就是說,當事務提交時,數(shù)據(jù)能夠瞬間復制到所有節(jié)點。但實際情況下,從節(jié)點 A 復制數(shù)據(jù)到節(jié)點 B,總是需要花費一定時間的。如果是相同機房,耗費時間可能是幾毫秒;如果是跨地域的機房,例如北京機房同步到廣州機房,耗費的時間就可能是幾十毫秒。這就意味著,CAP 理論中的 C 在實踐中是不可能完美實現(xiàn)的,在數(shù)據(jù)復制的過程中,節(jié)點 A 和節(jié)點 B 的數(shù)據(jù)并不一致。
不要小看了這幾毫秒或者幾十毫秒的不一致,對于某些嚴苛的業(yè)務場景,例如和金錢相關的用戶余額,或者和搶購相關的商品庫存,技術上是無法做到分布式場景下完美的一致性的。而業(yè)務上必須要求一致性,因此單個用戶的余額、單個商品的庫存,理論上要求選擇 CP 而實際上 CP 都做不到,只能選擇 CA。也就是說,只能單點寫入,其他節(jié)點做備份,無法做到分布式情況下多點寫入。
CAP 理論告訴我們分布式系統(tǒng)只能選擇 CP 或者 AP,但其實這里的前提是系統(tǒng)發(fā)生了“分區(qū)”現(xiàn)象。如果系統(tǒng)沒有發(fā)生分區(qū)現(xiàn)象,也就是說 P 不存在的時候(節(jié)點間的網(wǎng)絡連接一切正常),我們沒有必要放棄 C 或者 A,應該 C 和 A 都可以保證,這就要求架構設計的時候既要考慮分區(qū)發(fā)生時選擇 CP 還是 AP,也要考慮分區(qū)沒有發(fā)生時如何保證 CA。
同樣以用戶管理系統(tǒng)為例,即使是實現(xiàn) CA,不同的數(shù)據(jù)實現(xiàn)方式也可能不一樣:用戶賬號數(shù)據(jù)可以采用“消息隊列”的方式來實現(xiàn) CA,因為消息隊列可以比較好地控制實時性,但實現(xiàn)起來就復雜一些;而用戶信息數(shù)據(jù)可以采用“數(shù)據(jù)庫同步”的方式來實現(xiàn) CA,因為數(shù)據(jù)庫的方式雖然在某些場景下可能延遲較高,但使用起來簡單。
ACID
ACID 是數(shù)據(jù)庫管理系統(tǒng)為了保證事務的正確性而提出來的一個理論,ACID 包含四個約束,下面我來解釋一下。
Atomicity(原子性)
一個事務中的所有操作,要么全部完成,要么全部不完成,不會在中間某個環(huán)節(jié)結束。事務在執(zhí)行過程中發(fā)生錯誤,會被回滾到事務開始前的狀態(tài),就像這個事務從來沒有執(zhí)行過一樣。
Consistency(一致性)
在事務開始之前和事務結束以后,數(shù)據(jù)庫的完整性沒有被破壞。
Isolation(隔離性)
數(shù)據(jù)庫允許多個并發(fā)事務同時對數(shù)據(jù)進行讀寫和修改的能力。隔離性可以防止多個事務并發(fā)執(zhí)行時由于交叉執(zhí)行而導致數(shù)據(jù)的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
Durability(持久性)
事務處理結束后,對數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會丟失。
可以看到,ACID 中的 A(Atomicity)和 CAP 中的 A(Availability)意義完全不同,而 ACID 中的 C 和 CAP 中的 C 名稱雖然都是一致性,但含義也完全不一樣。ACID 中的 C 是指數(shù)據(jù)庫的數(shù)據(jù)完整性,而 CAP 中的 C 是指分布式節(jié)點中的數(shù)據(jù)一致性。再結合 ACID 的應用場景是數(shù)據(jù)庫事務,CAP 關注的是分布式系統(tǒng)數(shù)據(jù)讀寫這個差異點來看,其實 CAP 和 ACID 的對比就類似關公戰(zhàn)秦瓊,雖然關公和秦瓊都是武將,但其實沒有太多可比性。
BASE
BASE 是指基本可用(Basically Available)、軟狀態(tài)( Soft State)、最終一致性( Eventual Consistency),核心思想是即使無法做到強一致性(CAP 的一致性就是強一致性),但應用可以采用適合的方式達到最終一致性。
基本可用(Basically Available)
分布式系統(tǒng)在出現(xiàn)故障時,允許損失部分可用性,即保證核心可用。
軟狀態(tài)(Soft State)
允許系統(tǒng)存在中間狀態(tài),而該中間狀態(tài)不會影響系統(tǒng)整體可用性。這里的中間狀態(tài)就是 CAP 理論中的數(shù)據(jù)不一致。
最終一致性(Eventual Consistency)
系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一定時間后,最終能夠達到一致的狀態(tài)。
這里的關鍵詞是“一定時間” 和 “最終”,“一定時間”和數(shù)據(jù)的特性是強關聯(lián)的,不同的數(shù)據(jù)能夠容忍的不一致時間是不同的。舉一個微博系統(tǒng)的例子,用戶賬號數(shù)據(jù)最好能在 1 分鐘內(nèi)就達到一致狀態(tài)。因為用戶在 A 節(jié)點注冊或者登錄后,1 分鐘內(nèi)不太可能立刻切換到另外一個節(jié)點,但 10 分鐘后可能就重新登錄到另外一個節(jié)點了,而用戶發(fā)布的最新微博,可以容忍 30 分鐘內(nèi)達到一致狀態(tài)。因為對于用戶來說,看不到某個明星發(fā)布的最新微博,用戶是無感知的,會認為明星沒有發(fā)布微博?!白罱K”的含義就是不管多長時間,最終還是要達到一致性的狀態(tài)。
BASE 理論本質(zhì)上是對 CAP 的延伸和補充,更具體地說,是對 CAP 中 AP 方案的一個補充。前面在剖析 CAP 理論時,提到了其實和 BASE 相關的兩點:
CAP 理論是忽略延時的,而實際應用中延時是無法避免的。
這一點就意味著完美的 CP 場景是不存在的,即使是幾毫秒的數(shù)據(jù)復制延遲,在這幾毫秒時間間隔內(nèi),系統(tǒng)是不符合 CP 要求的。因此 CAP 中的 CP 方案,實際上也是實現(xiàn)了最終一致性,只是“一定時間”是指幾毫秒而已。
AP 方案中犧牲一致性只是指分區(qū)期間,而不是永遠放棄一致性。
這一點其實就是 BASE 理論延伸的地方,分區(qū)期間犧牲一致性,但分區(qū)故障恢復后,系統(tǒng)應該達到最終一致性。
綜合上面的分析,ACID 是數(shù)據(jù)庫事務完整性的理論,CAP 是分布式系統(tǒng)設計理論,BASE 是 CAP 理論中 AP 方案的延伸。今天我為你講了深入理解 CAP 理論所需要特別關注的細節(jié)點,以及 ACID 和 BASE 兩個相似的術語,這些技術細節(jié)在架構設計中非常關鍵,希望對你有所幫助
————————————————
歡迎各位小伙伴進群相互交流點擊鏈接