分布式系統(tǒng)的 CAP 定理與 BASE 理論
本文轉(zhuǎn)載自微信公眾號「碼農(nóng)私房話」,作者GoQeng。轉(zhuǎn)載本文請聯(lián)系碼農(nóng)私房話公眾號。
最近在總結(jié)之前面試騰訊財付通考察注冊中心的知識點,但寫著寫著發(fā)現(xiàn)有很多功能點需要基礎理論鋪墊,因此決定先總結(jié)分布式系統(tǒng)中常用的理論,方便后續(xù)對面試考察點的理解。
什么是 CAP ?
CAP 理論作為分布式系統(tǒng)的基礎理論,它描述的是一個分布式系統(tǒng)在以下三個特性中:
- 一致性(Consistency)
- 可用性(Availability)
- 分區(qū)容錯性(Partition Tolerance)
最多滿足其中的兩個特性,也就是下圖所描述的:分布式系統(tǒng)要么滿足 CA,要么 CP,要么 AP,而無法同時滿足 CAP。
分區(qū)容錯性:指分布式系統(tǒng)中的某個節(jié)點或網(wǎng)絡分區(qū)出現(xiàn)了故障時,整個系統(tǒng)仍然能對外提供滿足一致性和可用性的服務,也就是說部分故障不影響整體使用。
可用性:系統(tǒng)一直可以正常地做讀寫操作,簡單而言就是客戶端一直可以正常訪問并得到系統(tǒng)的正常響應,從用戶角度來看是不會出現(xiàn)系統(tǒng)操作失敗或者訪問超時等問題。
一致性:在分布式系統(tǒng)完成某寫操作后任何讀操作,都應該獲取到該寫操作寫入的那個最新的值。相當于要求分布式系統(tǒng)中的各節(jié)點時時刻刻保持數(shù)據(jù)的一致性。
如何理解 CAP ?
首先在保證了分區(qū)容錯性的前提下,意味著若某個節(jié)點故障了,用戶還可以繼續(xù)訪問,但這時用戶在訪問過程中就會出現(xiàn)一致性和可用性不能同時滿足的情況,如下圖:
情景一:
假設分布式系統(tǒng)有 S0、S1 兩個節(jié)點,節(jié)點中的變量初始值都是 v0,現(xiàn)在有一個客戶端向系統(tǒng)寫入了新值 v1,這里假設直接寫的是節(jié)點 S0,寫完之后客戶端再去讀取這個值,但此時讀到了 S1 節(jié)點的。
由于 S1 節(jié)點與 S0 節(jié)點失去通信,此時 S0 節(jié)點的數(shù)據(jù)還未同步到 S1 節(jié)點,因此客戶端讀取到的是舊的值 v0,這就出現(xiàn)不滿足一致性的情況,即滿足了可用性,失去了一致性。
情景二:
類似的,如果系統(tǒng)保證了強一致性,那么在客戶端往 S0 節(jié)點寫完數(shù)據(jù)后,S0 向 S1 節(jié)點同步數(shù)據(jù)出現(xiàn)了問題,此時如果客戶端再去讀取 S1 節(jié)點的數(shù)據(jù),客戶端就會一直處于等待狀態(tài),因為系統(tǒng)各節(jié)點的數(shù)據(jù)未同步完,需要等同步完才能使用,即滿足了一致性,而失去了可用性。
情景三:
當多個客戶端訪問的情況時,一致性與可用性可這么理解:假設客戶端1 向 S0 修改某個值的時候, 寫操作還未完成,客戶端2就發(fā)起來對該值的讀操作,但讀取的是 S1 節(jié)點的值,這時如果要滿足一致性,就得讓客戶端1暫時無法使用,如果要讓客戶端2可使用,那么獲取的數(shù)據(jù)不是最新的,系統(tǒng)就不滿足一致性。
CAP 三者不可得兼,如何取舍 ?
CA:優(yōu)先保證一致性和可用性,放棄分區(qū)容錯。這也意味著放棄系統(tǒng)的擴展性,系統(tǒng)不再是分布式的,有違設計的初衷。
CP:優(yōu)先保證一致性和分區(qū)容錯性,放棄可用性。在數(shù)據(jù)一致性要求比較高的場合,例如:Zookeeper、Hbase 等是比較常見的做法,一旦發(fā)生網(wǎng)絡故障或者消息丟失,就會犧牲用戶體驗,等恢復之后用戶才逐漸能訪問。
AP:優(yōu)先保證可用性和分區(qū)容錯性,放棄一致性。在 Spring Cloud 體系中使用的 Eureka 注冊中心就是這種架構(gòu),但放棄一致性只是指放棄強一致性,保證最終一致性。
什么是 BASE 理論 ?
BASE 全稱是 Basically Available(基本可用)、Soft State(軟狀態(tài))和 Eventually Consistent(最終一致性)三個短語的縮寫,來自 ebay 的架構(gòu)師提出。
Base 理論是對 CAP 中一致性和可用性權衡的結(jié)果,其來源于對大型互聯(lián)網(wǎng)分布式實踐的總結(jié),是基于 CAP 定理逐步演化而來的。
其核心思想是:既然無法做到強一致性,但每個應用都可以根據(jù)自身的業(yè)務特點,采用適當?shù)姆绞絹硎瓜到y(tǒng)達到最終一致性。
Basically Available(基本可用)
基本可用就是假設系統(tǒng)某個模塊出現(xiàn)了不可預知的故障,但其他模塊依舊可用,例如商城雙十一活動時,評論模塊出現(xiàn)故障,但不會影響交易、商品等核心模塊的流程使用。
Soft State(軟狀態(tài))
軟狀態(tài)指的是允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認為該狀態(tài)不影響系統(tǒng)的整體可用性,即允許系統(tǒng)在多個不同節(jié)點的數(shù)據(jù)副本存在數(shù)據(jù)延時。
用戶在商城下單時,因網(wǎng)絡超時等因素,訂單處于“支付中”的狀態(tài),待數(shù)據(jù)最終一致后狀態(tài)將變更為“關閉”或“成功”狀態(tài)。
Eventually Consistent(最終一致性)
上面講到的軟狀態(tài)不可能一直是軟狀態(tài),必須有時間期限。在期限過后,應當保證所有副本保持數(shù)據(jù)一致性,從而達到數(shù)據(jù)的最終一致性,因此所有客戶端對系統(tǒng)的數(shù)據(jù)訪問最終都能夠獲取到最新的值,而這個時間期限取決于網(wǎng)絡延時,系統(tǒng)負載,數(shù)據(jù)復制方案等因素。
在 CAP 中的一致性要求在任何時間查詢每個節(jié)點數(shù)據(jù)都必須一致,它強調(diào)的是強一致性,而最終一致性是允許在一段時間內(nèi)每個節(jié)點的數(shù)據(jù)不一致,但是經(jīng)過一段時間每個節(jié)點的數(shù)據(jù)必須一致,它強調(diào)的是最終數(shù)據(jù)的一致性。
在實際情景中,最終一致性分為 5 種:
1. 因果一致性(Causal consistency)
如果節(jié)點 A 在更新完某個數(shù)據(jù)后通知了節(jié)點 B,那么節(jié)點 B 之后對該數(shù)據(jù)的訪問和修改都是基于 A 更新后的值,但對和節(jié)點 A 無因果關系的節(jié)點 C 的數(shù)據(jù)訪問則沒這限制。
2. 讀己之所寫(Read your writes)
節(jié)點 A 更新一個數(shù)據(jù)后,它自身總是能訪問到自身更新過的最新值,而不會看到舊值。
3. 會話一致性(Session consistency)
會話一致性將對系統(tǒng)數(shù)據(jù)的訪問過程限定在一個會話當中:系統(tǒng)能保證在同一個有效的會話中實現(xiàn) “讀己之所寫” 的一致性,也就是說,執(zhí)行更新操作之后,客戶端能夠在同一個會話中始終讀取到該數(shù)據(jù)項的最新值。
4. 單調(diào)讀一致性( Read consistency)
單調(diào)讀一致性指如果一個節(jié)點從系統(tǒng)中讀取出一個數(shù)據(jù)項的某個值后,那么系統(tǒng)對于該節(jié)點后續(xù)的任何數(shù)據(jù)訪問都不應該返回更舊的值。
5. 單調(diào)寫一致性(Write consistency)
指一個系統(tǒng)要能夠保證來自同一個節(jié)點的寫操作被順序的執(zhí)行。
對于上面的 5 種最終一致性,在實際系統(tǒng)中往往會結(jié)合使用,以構(gòu)建一個具有最終一致性的分布式系統(tǒng)。
實際上,不只是分布式系統(tǒng)使用最終一致性,在關系型數(shù)據(jù)庫的某個功能上,也是使用最終一致性的,比如數(shù)據(jù)備份、數(shù)據(jù)庫主從復制等過程是需要時間的。
在復制過程中,業(yè)務讀取從服務器的值是舊的,經(jīng)過一定時間后,主從服務器才會達成數(shù)據(jù)一致性,這也是最終一致性的經(jīng)典案例。
最后總結(jié)
總的來說,BASE 理論面向的是大型高可用可擴展的分布式系統(tǒng),和傳統(tǒng)事務的 ACID 是相反的,它完全不同于 ACID 的強一致性模型,而是通過犧牲強一致性來獲得可用性,并允許數(shù)據(jù)在一段時間是不一致的。