分布式系統(tǒng)的三個(gè)指標(biāo):CAP理論
CAP的具體細(xì)節(jié)
ACID /BASE 理論
本文來自于《極客時(shí)間》- 從0開始學(xué)架構(gòu)
Consistency 一致性:
寫操作之后的讀操作,必須返回該值
Availability 可用性:
只要收到用戶的請求,服務(wù)器就必須給出回應(yīng)
Partition tolerance 分區(qū)容錯(cuò):
區(qū)間通信可能失敗。比如,一臺(tái)服務(wù)器放在中國,另一臺(tái)服務(wù)器放在美國,這就是兩個(gè)區(qū),它們之間可能無法通信。

CAP理論
CAP理論定義是三個(gè)要素中只能取兩個(gè)。
分布式系統(tǒng)中,網(wǎng)絡(luò)本身無法做到100%可靠,有可能出故障,所以P(分區(qū)容忍)是一個(gè)必然的現(xiàn)象,總是成立。
CAP 定理告訴我們,剩下的 C 和 A 無法同時(shí)做到。
因此,分布式系統(tǒng)理論上不可能選擇CA架構(gòu),只能選擇CP或者AP架構(gòu)。
CP
如圖所示,為保證一致性,當(dāng)發(fā)生分區(qū)現(xiàn)象后,N1節(jié)點(diǎn)上的數(shù)據(jù)已經(jīng)更新到y(tǒng),但由于N1和N2之間的復(fù)制通道中斷,數(shù)據(jù)y無法同步到N2,N2節(jié)點(diǎn)上的數(shù)據(jù)還是x。
這時(shí)客戶端C訪問N2時(shí),N2需要返回Error,提示客戶端C“系統(tǒng)現(xiàn)在發(fā)生了錯(cuò)誤”,這種處理方式違背了可用性(Availability)的要求,因此CAP三者只能滿足CP。

AP
如圖所示,為保證可用性,當(dāng)發(fā)生分區(qū)現(xiàn)象后,N1節(jié)點(diǎn)上的數(shù)據(jù)已經(jīng)更新到y(tǒng),但由于N1和N2之間的復(fù)制通道中斷,數(shù)據(jù)y無法同步到N2,N2節(jié)點(diǎn)上的數(shù)據(jù)還是x。
這時(shí)客戶端C訪問N2時(shí),N2將當(dāng)前自己擁有的數(shù)據(jù)x返回給客戶端C了,而實(shí)際上當(dāng)前最新的數(shù)據(jù)已經(jīng)是y了,這就不滿足一致性(Consistency)的要求了,因此CAP三者只能滿足AP
注 意:這里N2節(jié)點(diǎn)返回x,雖然不是一個(gè)“正確”的結(jié)果,但是一個(gè)“合理”的結(jié)果,因?yàn)閤是舊數(shù)據(jù),并不是一個(gè)錯(cuò)亂的值,只是不是最新的數(shù)據(jù)而已。

綜上所述,無法同時(shí)做到一致性和可用性。
系統(tǒng)設(shè)計(jì)時(shí)只能選擇一個(gè)目標(biāo)。如果追求一致性,那么無法保證所有節(jié)點(diǎn)的可用性;如果追求所有節(jié)點(diǎn)的可用性,那就沒法做到一致性。
問題:在什么場合,可用性高于一致性?
舉例來說,發(fā)布一張網(wǎng)頁到 CDN,多個(gè)服務(wù)器有這張網(wǎng)頁的副本。后來發(fā)現(xiàn)一個(gè)錯(cuò)誤,需要更新網(wǎng)頁,這時(shí)只能每個(gè)服務(wù)器都更新一遍。
一般來說,網(wǎng)頁的更新不是特別強(qiáng)調(diào)一致性。短時(shí)期內(nèi),一些用戶拿到老版本,另一些用戶拿到新版本,問題不會(huì)特別大。
當(dāng)然,所有人最終都會(huì)看到新版本。所以,這個(gè)場合就是可用性高于一致性。
CAP的具體細(xì)節(jié)
CAP關(guān)注的粒度是數(shù)據(jù),而不是整個(gè)系統(tǒng)。
在實(shí)際設(shè)計(jì)過程中,每個(gè)系統(tǒng)不可能只處理一種數(shù)據(jù),而是包含多種類型的數(shù)據(jù),有的數(shù)據(jù)必須選擇CP,有的數(shù)據(jù)必須選擇AP。
而如果我們做設(shè)計(jì)時(shí),從整個(gè)系統(tǒng)的角度去選擇CP還是AP,就會(huì)發(fā)現(xiàn)顧此失彼,無論怎么做都是有問題的。
案例:
最簡單的用戶管理系統(tǒng),用戶管理系統(tǒng)包含用戶賬號(hào)數(shù)據(jù)(用戶ID、密碼)、用戶信息數(shù)據(jù)(昵稱、興趣、愛好、性別、自我介紹等)。
通常情況下,用戶賬號(hào)數(shù)據(jù)會(huì)選 擇CP,而用戶信息數(shù)據(jù)會(huì)選擇AP,如果限定整個(gè)系統(tǒng)為CP,則不符合用戶信息數(shù)據(jù)的應(yīng)用場景;如果限定整個(gè)系統(tǒng)為AP,則又不符合用戶賬號(hào)數(shù)據(jù)的應(yīng)用場景。
所以在CAP理論落地實(shí)踐時(shí),我們需要將系統(tǒng)內(nèi)的數(shù)據(jù)按照不同的應(yīng)用場景和要求進(jìn)行分類,每類數(shù)據(jù)選擇不同的策略(CP還是AP),而不是直接限定整個(gè)系統(tǒng)所有數(shù)據(jù)都是同一策略。CAP是忽略網(wǎng)絡(luò)延遲的
當(dāng)事務(wù)提交時(shí),數(shù)據(jù)能夠瞬間復(fù)制到所有節(jié)點(diǎn)。
但實(shí)際情況下,從節(jié)點(diǎn)A復(fù)制數(shù)據(jù)到節(jié)點(diǎn)B, 總是需要花費(fèi)一定時(shí)間的。如果是相同機(jī)房,耗費(fèi)時(shí)間可能是幾毫秒;如果是跨地域的機(jī)房,例如北京機(jī)房同步到廣州機(jī)房,耗費(fèi)的時(shí)間就可能是幾十毫秒。
這就意味著,CAP理論 中的C在實(shí)踐中是不可能完美實(shí)現(xiàn)的,在數(shù)據(jù)復(fù)制的過程中,節(jié)點(diǎn)A和節(jié)點(diǎn)B的數(shù)據(jù)并不一致。
不要小看了這幾毫秒或者幾十毫秒的不一致,對(duì)于某些嚴(yán)苛的業(yè)務(wù)場景,
例如和金錢相關(guān)的用戶余額,或者和搶購相關(guān)的商品庫存,技術(shù)上是無法做到分布式場景下完美的一致性 的。而業(yè)務(wù)上必須要求一致性,因此單個(gè)用戶的余額、單個(gè)商品的庫存,理論上要求選擇CP而實(shí)際上CP都做不到,只能選擇CA。也就是說,只能單點(diǎn)寫入,其他節(jié)點(diǎn)做備份,無法 做到分布式情況下多點(diǎn)寫入。
需要注意的是,這并不意味著這類系統(tǒng)無法應(yīng)用分布式架構(gòu),只是說“單個(gè)用戶余額、單個(gè)商品庫存”無法做分布式,但系統(tǒng)整體還是可以應(yīng)用分布式架構(gòu)的。
案例:
常見的將用戶分區(qū)的分布式架構(gòu)

這樣的設(shè)計(jì)有一個(gè)很明顯的問題就是某個(gè)節(jié)點(diǎn)故障時(shí),這個(gè)節(jié)點(diǎn)上的用戶就無法進(jìn)行讀寫操作了,但站在整體上來看,這種設(shè)計(jì)可以降低節(jié)點(diǎn)故障時(shí)受影響的用戶的數(shù)量和范圍,畢 竟只影響20%的用戶肯定要比影響所有用戶要好。
這也是為什么挖掘機(jī)挖斷光纜后,支付寶只有一部分用戶會(huì)出現(xiàn)業(yè)務(wù)異常,而不是所有用戶業(yè)務(wù)異常的原因。
正常運(yùn)行情況下,不存在CP和AP的選擇,可以同時(shí)滿足CA。
CAP理論告訴我們分布式系統(tǒng)只能選擇CP或者AP,但其實(shí)這里的前提是系統(tǒng)發(fā)生了“分區(qū)”現(xiàn)象。如果系統(tǒng)沒有發(fā)生分區(qū)現(xiàn)象,也就是說P不存在的時(shí)候(節(jié)點(diǎn)間的網(wǎng)絡(luò)連接一切正常),我們沒有必要放棄C或者A,應(yīng)該C和A都可以保證,
這就要求架構(gòu)設(shè)計(jì)的時(shí)候既要考慮分區(qū)發(fā)生時(shí)選擇CP還是AP,也要考慮分區(qū)沒有發(fā)生時(shí)如何保證CA。
同樣以用戶管理系統(tǒng)為例,即使是實(shí)現(xiàn)CA,不同的數(shù)據(jù)實(shí)現(xiàn)方式也可能不一樣:
用戶賬號(hào)數(shù)據(jù)可以采用“消息隊(duì)列”的方式來實(shí)現(xiàn)CA,因?yàn)橄㈥?duì)列可以比較好地控制實(shí)時(shí)性,但實(shí)現(xiàn)起來就復(fù)雜一些;
而用戶信息數(shù)據(jù)可以采用“數(shù)據(jù)庫同步”的方式來實(shí)現(xiàn)CA,因?yàn)閿?shù)據(jù)庫的方式雖然在某些場景下可能延遲較高,但使用起來簡單。放棄并不等于什么都不做,需要為分區(qū)恢復(fù)后做準(zhǔn)備。
CAP理論告訴我們?nèi)咧荒苋蓚€(gè),需要“犧牲”(sacrifced)另外一個(gè),這里的“犧牲”是有一定誤導(dǎo)作用的,因?yàn)椤盃奚弊尯芏嗳死斫獬墒裁炊疾蛔觥?br> 實(shí)際上,CAP理論的“犧牲”只 是說在分區(qū)過程中我們無法保證C或者A,但并不意味著什么都不做。因?yàn)樵谙到y(tǒng)整個(gè)運(yùn)行周期中,大部分時(shí)間都是正常的,發(fā)生分區(qū)現(xiàn)象的時(shí)間并不長。
例如:
99.99%可用性(俗稱4個(gè)9)的系統(tǒng),一年運(yùn)行下來,不可用的時(shí)間只有50分鐘;
99.999%(俗稱5個(gè)9)可用性的系統(tǒng),一年運(yùn)行下來,不可用的時(shí)間只有5分鐘。
分區(qū)期間放棄C或者A,并不意味著永遠(yuǎn)放棄C和A。
我們可以在分區(qū)期間進(jìn)行一些操作,從而讓分區(qū)故障解決后,系統(tǒng)能夠重新達(dá)到CA的狀態(tài)。
最典型的就是在分區(qū)期間記錄一些日志,當(dāng)分區(qū)故障解決后,系統(tǒng)根據(jù)日志進(jìn)行數(shù)據(jù)恢復(fù),使得重新達(dá)到CA狀態(tài)。
案例:
以用戶管理系統(tǒng)為例,對(duì)于用戶賬號(hào)數(shù)據(jù),假設(shè)我們選擇 了CP,則分區(qū)發(fā)生后,節(jié)點(diǎn)1可以繼續(xù)注冊新用戶,節(jié)點(diǎn)2無法注冊新用戶(這里就是不符合A的原因,因?yàn)楣?jié)點(diǎn)2收到注冊請求后會(huì)返回error),此時(shí)節(jié)點(diǎn)1可以將新注冊但未同步 到節(jié)點(diǎn)2的用戶記錄到日志中。
當(dāng)分區(qū)恢復(fù)后,節(jié)點(diǎn)1讀取日志中的記錄,同步給節(jié)點(diǎn)2,當(dāng)同步完成后,節(jié)點(diǎn)1和節(jié)點(diǎn)2就達(dá)到了同時(shí)滿足CA的狀態(tài)。
而對(duì)于用戶信息數(shù)據(jù),假設(shè)我們選擇了AP,則分區(qū)發(fā)生后,節(jié)點(diǎn)1和節(jié)點(diǎn)2都可以修改用戶信息,但兩邊可能修改不一樣。例如,用戶在節(jié)點(diǎn)1中將愛好改為“旅游、美食、跑步”,然 后用戶在節(jié)點(diǎn)2中將愛好改為“美食、游戲”,節(jié)點(diǎn)1和節(jié)點(diǎn)2都記錄了未同步的愛好數(shù)據(jù)。
當(dāng)分區(qū)恢復(fù)后,系統(tǒng)按照某個(gè)規(guī)則來合并數(shù)據(jù)。例如,按照“最后修改優(yōu)先規(guī)則”將用戶愛好 修改為“美食、游戲”,按照“字?jǐn)?shù)最多優(yōu)先規(guī)則”則將用戶愛好修改為“旅游,美食、跑步”,也可以完全將數(shù)據(jù)沖突報(bào)告出來,由人工來選擇具體應(yīng)該采用哪一條。
ACID:了保證事務(wù)的正確性
1.原子性 Atomicity
2.一致性 Consistency
3.隔離性 Isolation
4.持久性Durability
1.Atomicity(原子性)
一個(gè)事務(wù)中的所有操作,要么全部完成,要么全部不完成,不會(huì)在中間某個(gè)環(huán)節(jié)結(jié)束。
事務(wù)在執(zhí)行過程中發(fā)生錯(cuò)誤,會(huì)被回滾到事務(wù)開始前狀態(tài),就像這個(gè)事務(wù)從沒有執(zhí)行過一樣。
2.Consistency(一致性)
在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫的完整性沒有被破壞。
3.Isolation(隔離性)
數(shù)據(jù)庫允許多個(gè)并發(fā)事務(wù)同時(shí)對(duì)數(shù)據(jù)進(jìn)行讀寫和修改的能力。
隔離性可以防止多個(gè)事務(wù)并發(fā)執(zhí)行時(shí)由于交叉執(zhí)行而導(dǎo)致數(shù)據(jù)的不一致。
事務(wù)隔離分為不同級(jí)別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)。
4.Durability(持久性)
事務(wù)處理結(jié)束后,對(duì)數(shù)據(jù)的修改就是永久的,即便系統(tǒng)故障也不會(huì)丟失。
可以看到,ACID中的A(Atomicity)和CAP中的A(Availability)意義完全不同,而ACID中的C和CAP中的C名稱雖然都是一致性,但含義也完全不一樣。
ACID中的C是指數(shù)據(jù)庫的數(shù)據(jù)完整性,而CAP中的C是指分布式節(jié)點(diǎn)中的數(shù)據(jù)一致性。
再結(jié)合ACID的應(yīng)用場景是數(shù)據(jù)庫事務(wù),CAP關(guān)注的是分布式系統(tǒng)數(shù)據(jù)讀寫這個(gè)差異點(diǎn)來看。
其實(shí)CAP和ACID的對(duì)比 就類似關(guān)公戰(zhàn)秦瓊,雖然關(guān)公和秦瓊都是武將,但其實(shí)沒有太多可比性。
BASE
BASE是指基本可用(Basically Available)、軟狀態(tài)( Soft State)、最終一致性( Eventual Consistency)。
核心思想是即使無法做到強(qiáng)一致性(CAP的一致性就是強(qiáng)一致 性),但應(yīng)用可以采用適合的方式達(dá)到最終一致性。
1.基本可用(Basically Available)
分布式系統(tǒng)在出現(xiàn)故障時(shí),允許損失部分可用性,即保證核心可用。
這里的關(guān)鍵詞是“部分”和“核心”,具體選擇哪些作為可以損失的業(yè)務(wù),哪些是必須保證的業(yè)務(wù),是一項(xiàng)有挑戰(zhàn)的工作。
例如,對(duì)于一個(gè)用戶管理系統(tǒng)來說,“登錄”是核心功能,而“注冊”可以算作非核心功能。
因?yàn)槲醋缘挠脩舯緛砭瓦€沒有使用系統(tǒng)的業(yè)務(wù),注冊不了最多就是流失一部分用戶,而且這部分用戶數(shù)量較少。
如果用戶已經(jīng)注冊但無法登錄,那就意味用戶無法使用系統(tǒng)。例如,充了錢的游戲不能玩了、云存儲(chǔ)不能用了......這些會(huì)對(duì)用戶造成較大損失,而且登錄用戶數(shù)量遠(yuǎn)遠(yuǎn)大于新注冊用戶,影響范圍更大。
2.軟狀態(tài)(Soft State) 允許系統(tǒng)存在中間狀態(tài),而該中間狀態(tài)不會(huì)影響系統(tǒng)整體可用性。
這里的中間狀態(tài)就是CAP理論中的數(shù)據(jù)不一致。
3.最終一致性(Eventual Consistency)
系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一定時(shí)間后,最終能夠達(dá)到一致的狀態(tài)。
這里的關(guān)鍵詞是“一定時(shí)間” 和 “最終”,“一定時(shí)間”和數(shù)據(jù)的特性是強(qiáng)關(guān)聯(lián)的,不同的數(shù)據(jù)能夠容忍的不一致時(shí)間是不同的。
案例:微博系統(tǒng)
用戶賬號(hào)數(shù)據(jù)最好能在1分鐘內(nèi)就達(dá)到一致狀態(tài),因?yàn)橛脩粼贏節(jié)點(diǎn)注冊或者登錄后,1分鐘內(nèi)不太可能立刻切換到另外一個(gè)節(jié)點(diǎn),但10分鐘后可能就重新登錄到另外一個(gè)節(jié)點(diǎn)了;
用戶發(fā)布最新微博,可以容忍30分鐘內(nèi)達(dá)到一致狀態(tài),對(duì)于用戶來說,看不到某個(gè)明星發(fā)布的最新微博,用戶無感知,會(huì)認(rèn)為明星沒有發(fā)布微博。
“最終”的含義就是不管多長時(shí)間,最終還是要達(dá)到一 致性的狀態(tài)。
BASE理論本質(zhì)上是對(duì)CAP的延伸和補(bǔ)充,更具體地說,是對(duì)CAP中AP方案的一個(gè)補(bǔ)充。
前面在剖析CAP理論時(shí),提到了其實(shí)和BASE相關(guān)的兩點(diǎn):
1)CAP理論是忽略延時(shí)的,而實(shí)際應(yīng)用中延時(shí)是無法避免的。
這一點(diǎn)就意味著完美的CP場景是不存在的,即使是幾毫秒的數(shù)據(jù)復(fù)制延遲,在這幾毫秒時(shí)間間隔內(nèi),系統(tǒng)是不符合CP要求的。
因此CAP中的CP方案,實(shí)際上也是實(shí)現(xiàn)了最終一致 性,只是“一定時(shí)間”是指幾毫秒而已。
2)AP方案中犧牲一致性只是指分區(qū)期間,而不是永遠(yuǎn)放棄一致性。
這一點(diǎn)其實(shí)就是BASE理論延伸的地方,分區(qū)期間犧牲一致性,但分區(qū)故障恢復(fù)后,系統(tǒng)應(yīng)該達(dá)到最終一致性。
總結(jié):
ACID是數(shù)據(jù)庫事務(wù)完整性的理論,CAP是分布式系統(tǒng)設(shè)計(jì)理論,BASE是CAP理論中AP方案的延伸。
案例:
一個(gè)電商網(wǎng)站核心模塊有會(huì)員,訂單,商品,支付,促銷管理等。
1)會(huì)員模塊,包括登錄,個(gè)人設(shè)置,個(gè)人訂單,購物車,收藏夾等,這些模塊保證AP,數(shù)據(jù)短時(shí)間不一致不影響使用。
2)訂單模塊的下單付款扣減庫存操作是整個(gè)系統(tǒng)的核心,CA都需要保證,在極端情況下犧牲P是可以的。
3)商品模塊的商品上下架和庫存管理保證CP/CA, 搜索功能因?yàn)楸旧砭筒皇菍?shí)時(shí)性非常高的模塊,所以保證AP就可以了。
4)促銷是短時(shí)間的數(shù)據(jù)不一致,結(jié)果就是優(yōu)惠信息看不到,但是已有的優(yōu)惠要保證可用,而且優(yōu)惠可以提前預(yù)計(jì)算,所以可以保證AP 現(xiàn)在大部分的電商網(wǎng)站對(duì)于支付這一塊是獨(dú)立的系統(tǒng),或者使用第三方的支付寶,微信。
其實(shí)CAP是由第三方來保證的,支付系統(tǒng)是一個(gè)對(duì)CAP要求極高的系統(tǒng),C是必須要保證的,AP中A相對(duì) 更重要,不能因?yàn)榉謪^(qū),導(dǎo)致所有人都不能支付
區(qū)分不同數(shù)據(jù):對(duì)關(guān)鍵信息采用ca,非關(guān)鍵信息采用ap,最終達(dá)到base即可
比如:商品信息顯示可細(xì)分為關(guān)鍵商品信息(如價(jià)格,庫存) CA和非關(guān)鍵信息(商品介紹,用戶評(píng)論)AP