肝了3版才滿意:分布式系統(tǒng)之CAP理論,我們對它的理解和誤解
引言
CAP 理論,相信很多人都聽過,它是指:
一個分布式系統(tǒng)最多只能同時(shí)滿足一致性(Consistency)、可用性(Availability)和分區(qū)容錯性(Partition tolerance)這三項(xiàng)中的兩項(xiàng)。
為什么要理解 CAP 理論?我能說出很多理由來。如果是在職場上,也許最合適的理由是,當(dāng)領(lǐng)導(dǎo)給出的任務(wù)不靠譜時(shí),我們可以依據(jù) CAP 去否決它。
比如,有這么一個任務(wù),給你定了三大目標(biāo):
- 既要提升系統(tǒng)的可用性
- 又要保證數(shù)據(jù)的實(shí)時(shí)可見
- 還有提升系統(tǒng)的容錯能力
看到“既要、又要、還要”,是不是想到了阿里……
OK,如果你深刻理解了 CAP,你會發(fā)現(xiàn)完成這個任務(wù)是不可能的。但是,如果你不理解 CAP,然后又拍了胸脯保證完成任務(wù),不好意思,職場是不需要眼淚和后悔的。
有點(diǎn)跑題了,書歸正傳。CAP 理論是分布式設(shè)計(jì)中最基礎(chǔ)最重要的理論,不懂它,你可能連分析一套分布式系統(tǒng)的核心設(shè)計(jì)理念都做不到。
關(guān)于 CAP 為何你讀了那么多文章都還是搞不明白呢?因?yàn)?CAP 理論來自學(xué)術(shù)界,而解讀 CAP 理論的人嘗試用工程師的方式去闡述它,這本身就有了問題。
CAP 本身基于狀態(tài),基于瞬態(tài),是一個描述性的理論,它并不解決工程問題。但是,很多工程師卻總是嘗試為 CAP 做過多解讀。比如,非要說 CAP 理論只能適合某某場景,非要說 CAP 理論里的一致性是非常強(qiáng)的一致性,把其和事務(wù)的一致性混為一談。
由于 CAP 是學(xué)術(shù)理論,并不是工程理論,它會舍棄很多現(xiàn)實(shí)世界的問題。比如網(wǎng)絡(luò)的時(shí)長,比如節(jié)點(diǎn)內(nèi)部的處理速度不一致,比如節(jié)點(diǎn)間存儲方式和速度的不一致。它說的一致性就是客戶端是否能拿到最新數(shù)據(jù),它說的可用性就是允許客戶端拿不到最新數(shù)據(jù)。而這些東西被工程師們的過多腦補(bǔ),導(dǎo)致了文章和文章說法不一樣,解析不一樣,闡述背景不一樣。
在今天這篇文章中,我們只解釋和說明,不腦補(bǔ),不過多從工程角度解讀,只說本質(zhì),只指核心,希望能真正說清楚、講明白 CAP 理論。望本文能達(dá)到這個目的。
接下來你看到文字,我前前后后寫了 10 天,已經(jīng)是這篇文章的第三版了,前兩版寫了一半都被我推翻重寫了,因?yàn)槲易约嚎戳瞬粷M意。
一方面是對自己知識掌握程度不滿意,本以為自己明白 CAP 了,直到寫的時(shí)候,發(fā)現(xiàn)有些還是拿不準(zhǔn)。
另一方面是不滿意自己的寫的太晦澀、太教科書,能把知識講的通俗易懂,才是我希望的。
給大家看看文章上輩子的模樣。
1. CAP 的由來
要理解 CAP,首先我們要清楚,為何會有人提出 CAP?提出 CAP 是為了解決什么問題?
時(shí)間回到 1985 年,彼時(shí),后來證明了 CAP 理論的 Lynch 教授此時(shí)給當(dāng)時(shí)的 IT 界來了一記驚雷:
她通過不可辯駁的證明告訴業(yè)界的工程師們,如果在一個不穩(wěn)定(消息要么亂序要么丟了)的網(wǎng)絡(luò)環(huán)境里(分布式異步模型),想始終保持?jǐn)?shù)據(jù)一致是不可能的。
這是個什么概念呢?就是她打破了那些既想提供超高質(zhì)量服務(wù),又想提供超高性能服務(wù)的技術(shù)人員的幻想。
這本質(zhì)是在告訴大家,在分布式系統(tǒng)里,需要妥協(xié)。
但是,如何妥協(xié)?分布式系統(tǒng)里到底應(yīng)該怎么權(quán)衡這種 trade-off?
我們可以想象一下,在 CAP 定理提出之前,沒有這些方向性的指引,在設(shè)計(jì)和實(shí)施分布式系統(tǒng)時(shí)該有多么混亂。一套分布式系統(tǒng)是由多個模塊組成的,這些模塊本身可能由不同的開發(fā)人員去完成。然而,對于這些人,在公共層面,竟然沒有一個原則去指導(dǎo)他們該怎么完成這套功能。
比如,我們在同步兩個節(jié)點(diǎn)的數(shù)據(jù)時(shí),如果發(fā)生了錯誤,到底我們應(yīng)該怎么做呢?如果沒有統(tǒng)一的標(biāo)準(zhǔn)和方向,那很可能在一套分布式系統(tǒng)中的不同模塊,會出現(xiàn)不同的處理情況。
假設(shè)一套系統(tǒng),由 A、B 兩個模塊構(gòu)成。
A 模塊的設(shè)計(jì)理念是:節(jié)點(diǎn)間出現(xiàn)了問題,它可能會選擇不斷的重試,一直等到節(jié)點(diǎn)通信恢復(fù)。
而 B 的設(shè)計(jì)理念是:節(jié)點(diǎn)間出現(xiàn)了問題,它斷開就是了,可能最多就記錄下狀態(tài),等以后處理。
可是,當(dāng) A、B 之間出現(xiàn)了通信怎么辦?那會出現(xiàn) A 往 B 發(fā)請求,出問題會不斷重試。而 B 往 A 發(fā)請求,出問題則直接斷開的情況。
當(dāng)然,在后面我們會說明,CAP 的理念在實(shí)際工程中,會允許這種不一致??墒牵欠N不一致是提前設(shè)計(jì)好和規(guī)劃好的,是根據(jù)實(shí)際數(shù)據(jù)的重要性和業(yè)務(wù)需求做的妥協(xié),而不是這種混亂的妥協(xié)。
所以,IT 界的人們就一直在摸索,試圖找到一些綱領(lǐng)去指導(dǎo)分布式系統(tǒng)的設(shè)計(jì),這一找就找了 15 年。
2000 年時(shí),Eric Brewer 教授在 PODC 會議上提出了 CAP 理論,但是由于沒有被證明過,所以,當(dāng)時(shí)只能被稱為 CAP 猜想。這個猜想引起了巨大的反響,因?yàn)?CAP 很符合人們對設(shè)計(jì)綱領(lǐng)的預(yù)期。
在 2002 年后,經(jīng)過 Seth Gilbert 和 Nancy Lynch 從理論上證明了 CAP 猜想后,CAP 理論正式成為了分布式系統(tǒng)理論的基石之一。
2. CAP 到底是什么
CAP 定理表達(dá)了一個分布式系統(tǒng)里不可能同時(shí)滿足以下的三個特性:
2.1. C:數(shù)據(jù)一致性
什么是數(shù)據(jù)一致性?咋一看真的很讓人糊涂,一致性是什么?是指數(shù)據(jù)能一起變化,是能讓數(shù)據(jù)整齊劃一。
那么問題又來了,數(shù)據(jù)何時(shí)會變化?數(shù)據(jù)怎么才能被稱為一起變化?我們現(xiàn)在來回答這些問題,當(dāng)我們搞清楚了這些問題,那么對數(shù)據(jù)一致性就會有了清晰的理解。
首先第一個問題,數(shù)據(jù)何時(shí)會一起變化?
答案是:僅且僅當(dāng)包含數(shù)據(jù)的服務(wù),收到數(shù)據(jù)更新請求的時(shí)候,數(shù)據(jù)才會發(fā)生變化。而數(shù)據(jù)更新請求則僅包括數(shù)據(jù)的增、刪、改這三種請求,而這三種請求又被統(tǒng)稱為寫請求。所以,數(shù)據(jù)只有在寫請求的時(shí)候才會發(fā)生變化。
那我們來回答第二個問題,數(shù)據(jù)要怎么樣才能被稱為一起變化了?即誰來判斷數(shù)據(jù)是最終變化了?是服務(wù)器對寫請求的返回結(jié)果嗎?告訴寫請求成功,數(shù)據(jù)就一定發(fā)生一致性變化了?
NO,數(shù)據(jù)發(fā)生變化是否一致是需要經(jīng)過讀請求來做檢驗(yàn)的。那么讀請求判斷的依據(jù)是什么呢?
假設(shè),我們的分布式存儲系統(tǒng)有兩個節(jié)點(diǎn),每個節(jié)點(diǎn)都包含了一部分需要被變化的數(shù)據(jù)。如果經(jīng)過一次寫請求后,兩個節(jié)點(diǎn)都發(fā)生了數(shù)據(jù)變化。然后,讀請求把這些變化后的數(shù)據(jù)都讀取到了,我們就把這次數(shù)據(jù)修改稱為數(shù)據(jù)發(fā)生了一致性變化。
但是,這還不是完整的一致性。因?yàn)橄到y(tǒng)不可能永久的正常運(yùn)行下去。
如果系統(tǒng)內(nèi)部發(fā)生了問題從而導(dǎo)致系統(tǒng)的節(jié)點(diǎn)無法發(fā)生一致性變化會怎么樣呢?當(dāng)我們這樣做的時(shí)候,就意味著想看到最新數(shù)據(jù)的讀請求們,很可能會看到舊數(shù)據(jù),或者說獲取到不同版本的數(shù)據(jù)。此時(shí),為了保證分布式系統(tǒng)對外的數(shù)據(jù)一致性,于是選擇不返回任何數(shù)據(jù)。
這里需要注意一下,CAP 定理是在說在某種狀態(tài)下的選擇,和實(shí)際工程的理論是有差別的。上面描述的一致性和 ACID 事務(wù)中的一致性是兩回事。事務(wù)中的一致性包含了實(shí)際工程對狀態(tài)的后續(xù)處理。但是 CAP 定理并不涉及到狀態(tài)的后續(xù)處理,對于這些問題,后續(xù)出現(xiàn)了 BASE 理論等工程結(jié)論去處理,目前,只需要明白 CAP 定理主要描述的是狀態(tài)。
2.2. A:可用性
奧維德曾經(jīng)說過:“行動被人們遺忘,結(jié)果卻將永存”。
這句話說明了結(jié)果的重要性,而可用性在 CAP 里就是對結(jié)果的要求。它要求系統(tǒng)內(nèi)的節(jié)點(diǎn)們接收到了無論是寫請求還是讀請求,都要能處理并給回響應(yīng)結(jié)果。只是它有兩點(diǎn)必須滿足的條件:
條件 1:返回結(jié)果必須在合理的時(shí)間以內(nèi),這個合理的時(shí)間是根據(jù)業(yè)務(wù)來定的。業(yè)務(wù)說必須 100 毫秒內(nèi)返回,合理的時(shí)間就是 100 毫秒,需要 1 秒內(nèi)返回,那就是 1 秒,如果業(yè)務(wù)定的 100 毫秒,結(jié)果卻在 1 秒才返回,那么這個系統(tǒng)就不滿足可用性。
條件 2:需要系統(tǒng)內(nèi)能正常接收請求的所有節(jié)點(diǎn)都返回結(jié)果。這包含了兩重含義:
-
如果節(jié)點(diǎn)不能正常接收請求了,比如宕機(jī)了,系統(tǒng)崩潰了,而其他節(jié)點(diǎn)依然能正常接收請求,那么,我們說系統(tǒng)依然是可用的,也就是說,部分宕機(jī)沒事兒,不影響可用性指標(biāo)。
-
如果節(jié)點(diǎn)能正常接收請求,但是發(fā)現(xiàn)節(jié)點(diǎn)內(nèi)部數(shù)據(jù)有問題,那么也必須返回結(jié)果,哪怕返回的結(jié)果是有問題的。比如,系統(tǒng)有兩個節(jié)點(diǎn),其中有一個節(jié)點(diǎn)數(shù)據(jù)是三天前的,另一個節(jié)點(diǎn)是兩分鐘前的,如果,一個讀請求跑到了包含了三天前數(shù)據(jù)的那個節(jié)點(diǎn)上,抱歉,這個節(jié)點(diǎn)不能拒絕,必須返回這個三天前的數(shù)據(jù),即使它可能不太合理。
2.3. P:分區(qū)容忍性
分布式的存儲系統(tǒng)會有很多的節(jié)點(diǎn),這些節(jié)點(diǎn)都是通過網(wǎng)絡(luò)進(jìn)行通信。而網(wǎng)絡(luò)是不可靠的,當(dāng)節(jié)點(diǎn)和節(jié)點(diǎn)之間的通信出現(xiàn)了問題,此時(shí),就稱當(dāng)前的分布式存儲系統(tǒng)出現(xiàn)了分區(qū)。但是,值得一提的是,分區(qū)并不一定是由網(wǎng)絡(luò)故障引起的,也可能是因?yàn)闄C(jī)器故障。
比如,我們的分布式存儲系統(tǒng)有 A、B 兩個節(jié)點(diǎn)。那么,當(dāng) A、B 之間由于可能路由器、交換機(jī)等底層網(wǎng)絡(luò)設(shè)備出現(xiàn)了故障,A 和 B 通信出現(xiàn)了問題,但是 A、B 依然都在運(yùn)行,都在對外提供服務(wù)。這時(shí)候,就說 A 和 B 發(fā)生了分區(qū)。
還有一種情況也會發(fā)生分區(qū),當(dāng) A 出現(xiàn)了宕機(jī),A 和 B 節(jié)點(diǎn)之間通信也是出現(xiàn)了問題,那么我們也稱 A 和 B 發(fā)生了分區(qū)。
綜上,我們可以知道,只要在分布式系統(tǒng)中,節(jié)點(diǎn)通信出現(xiàn)了問題,那么就出現(xiàn)了分區(qū)。
那么,分區(qū)容忍性是指什么? 它是說,如果出現(xiàn)了分區(qū)問題,我們的分布式存儲系統(tǒng)還需要繼續(xù)運(yùn)行。不能因?yàn)槌霈F(xiàn)了分區(qū)問題,整個分布式節(jié)點(diǎn)全部就熄火了,罷工了,不做事情了。
3. CAP 怎么選擇
我們上面已經(jīng)知道了,在設(shè)計(jì)分布式系統(tǒng)時(shí),架構(gòu)師們在 C、A、P 這三種特性里,只能選擇兩種。
但是,這道 CAP 的選擇題,就像別人在問你“小明的父親有三個孩子,老大叫大朗,老二叫二郎,請問老三叫什么”一樣。在以分布式存系統(tǒng)為限定條件的 CAP 世界里,P 是早已經(jīng)確定的答案,P 是必須的。
因?yàn)?,在分布式系統(tǒng)內(nèi),P 是必然的發(fā)生的,不選 P,一旦發(fā)生分區(qū)錯誤,整個分布式系統(tǒng)就完全無法使用了,這是不符合實(shí)際需要的。所以,對于分布式系統(tǒng),我們只能能考慮當(dāng)發(fā)生分區(qū)錯誤時(shí),如何選擇一致性和可用性。
而根據(jù)一致性和可用性的選擇不同,開源的分布式系統(tǒng)往往又被分為 CP 系統(tǒng)和 AP 系統(tǒng)。
當(dāng)一套系統(tǒng)在發(fā)生分區(qū)故障后,客戶端的任何請求都被卡死或者超時(shí),但是,系統(tǒng)的每個節(jié)點(diǎn)總是會返回一致的數(shù)據(jù),則這套系統(tǒng)就是 CP 系統(tǒng),經(jīng)典的比如 Zookeeper。
如果一套系統(tǒng)發(fā)生分區(qū)故障后,客戶端依然可以訪問系統(tǒng),但是獲取的數(shù)據(jù)有的是新的數(shù)據(jù),有的還是老數(shù)據(jù),那么這套系統(tǒng)就是 AP 系統(tǒng),經(jīng)典的比如 Eureka。
說了這么多,其實(shí) CAP 定理本質(zhì)很簡單,它就是一種分布式系統(tǒng)設(shè)計(jì)的不同理念概括,包括它說的一致性,可用性和分區(qū)容錯性。這就類似一個大學(xué)的校訓(xùn),是極度概念化的東西。
所以,大白話來形容下 CAP 吧,CAP 就是告訴程序員們當(dāng)分布式系統(tǒng)出現(xiàn)內(nèi)部問題了,你要做兩種選擇:
- 要么遷就外部服務(wù),像外包公司。
- 要么讓外部服務(wù)遷就你,像銀行。
遷就外部服務(wù)就是我們不能因?yàn)槲覀冏约旱膯栴}讓外部服務(wù)的業(yè)務(wù)運(yùn)行受到影響,所以要優(yōu)先可用性。而讓外部服務(wù)遷就我們,就要優(yōu)先一致性。
4. 對 CAP 的常見誤解
誤解一:分布式系統(tǒng)因?yàn)?CAP 定理放棄了 C 或者 A 中的其中一個
很多人在沒有對 CAP 做深入了解的情況下,聽到很多人說分布式系統(tǒng)必須在 CAP 三個特性里選擇兩個,就覺得一套分布式系統(tǒng)肯定要么只有可用性要么只有一致性,不存在完整的可用性和一致性功能。
這種理解是大有問題的。因?yàn)?,P 這種問題發(fā)生的概率非常低,所以:
當(dāng)沒有出現(xiàn)分區(qū)問題的時(shí)候,系統(tǒng)就應(yīng)該有完美的數(shù)據(jù)一致性和可用性。
你什么時(shí)候見過一個系統(tǒng),當(dāng)內(nèi)部沒有問題的時(shí)候,會經(jīng)常讓外部請求卡一下的?要么就冷不丁的提供陳舊的老數(shù)據(jù)?那還能叫系統(tǒng)嗎?
誤解二:C 和 A 之間的選擇是針對整個分布式系統(tǒng)的,只能整體考慮 C 和 A 之間的選擇
這個理解也是不對的。當(dāng)分區(qū)發(fā)生的時(shí)候,其實(shí)對一致性和可用性的抉擇是局部性的,而不是針對整個系統(tǒng)的。
可能是在一些子系統(tǒng)做一些抉擇,甚至很可能只需要對某個事件或者數(shù)據(jù),做一致性和可用性的抉擇而已。
比如,當(dāng)我們做一套支付系統(tǒng)的時(shí)候,會員的財(cái)務(wù)相關(guān)像賬戶余額,賬務(wù)流水是必須強(qiáng)一致性的。這時(shí)候,你就要考慮選 C。但是,會員的名字,會員的支付設(shè)置就不必考慮強(qiáng)一致性,可以選擇可用性 A。
一套分布式系統(tǒng)的運(yùn)行,就像人生一樣,就是一次又一次的選擇。在不同階段,不同的時(shí)刻有不同的事件發(fā)生的時(shí)候,又怎么可能會有完全一樣的選擇呢?
誤解三:CAP 的三個特性只有是和否兩種極端選擇,而不是一個范圍
這種二元性的理解更是極其誤導(dǎo)人。
CAP 理論的三種特性不是 Boolean 類型的,不是一致和不一致,可用和不可用,分區(qū)和沒分區(qū)的這類二選一的選項(xiàng)。而是這三種特性都是范圍類型。
拿可用性來說,就像我從銀行取錢。當(dāng)我目的是派發(fā)壓歲錢的時(shí)候,我很可能就想全要新票子,但是,新票子很可能就還得多一個步驟,就是需要拿舊票子去換一些新票,此時(shí),我可以多等會兒,能拿到新票子就好。而當(dāng)我的目的就是做生活花銷的時(shí)候,票子是新是舊,我根本不那么關(guān)心,快點(diǎn)拿到錢就行。這就是可用性的范圍需求之一,對時(shí)延性的要求。
再比如,分區(qū)容錯則由于探測機(jī)制的問題,可能還得各節(jié)點(diǎn)搞投票去協(xié)商分區(qū)是否存在,當(dāng)某一臺機(jī)器出現(xiàn)了問題,可能不影響業(yè)務(wù)的話,就會被機(jī)器投票認(rèn)為分區(qū)不存在。然后一直等到多數(shù)機(jī)器出現(xiàn)了問題,才會投票確認(rèn)出現(xiàn)了分區(qū)問題。這就好像新冠疫情,還會分低、中、高風(fēng)險(xiǎn)區(qū)呢,不是一出現(xiàn)通信故障就都被邏輯認(rèn)定為分區(qū)問題。
5. CAP 理論的一些疑問
疑問一:在遵從 CAP 定理的系統(tǒng)中是否適合任意的寫請求
首先,在 CAP 定理中,關(guān)于一致性會有多種說法,但是總的來說,都是在描述數(shù)據(jù)最新版本的可見性。而這些可見性往往代表的是讀請求返回的數(shù)據(jù)的可見性。
那么問題來了,當(dāng)我們要求讀數(shù)據(jù)的可見性的時(shí)候,對寫數(shù)據(jù)有什么要求嗎?
比如,我們系統(tǒng)有三個節(jié)點(diǎn),一個客戶端給這個系統(tǒng)發(fā)了一個寫請求,要求系統(tǒng)寫入一個值為 20 的數(shù)據(jù)。那么,如果要滿足 CAP 定理中的一致性,就需要在寫完 20 這個數(shù)據(jù)之后,當(dāng)其他客戶端請求讀取這個值為 20 的數(shù)據(jù)之后,無論請求被轉(zhuǎn)發(fā)到系統(tǒng)中任何節(jié)點(diǎn)都能返回這個值。
這就要求寫入這個值為 20 的寫請求必須成功寫到三個節(jié)點(diǎn)上,此時(shí),系統(tǒng)就滿足了寫一致性的。所以,我們可以說對于讀一致性的要求是同時(shí)約束了寫一致性的。
其次,在 CAP 定理中,可用性本身要求對讀、寫請求都要處理。如果我們以可用性作為標(biāo)準(zhǔn)的時(shí)候,在發(fā)生分區(qū)錯誤時(shí),由于我們對讀請求并沒有強(qiáng)行要求返回完全準(zhǔn)確的數(shù)據(jù),所以,可能在本次讀請求之前的最近一次寫請求可能是部分失敗的。
同樣的例子,我們的分布式系統(tǒng)由三個節(jié)點(diǎn)組成,最近一次寫請求想把值為 20 的數(shù)據(jù)寫到三個節(jié)點(diǎn)上。但是,由于發(fā)生了分區(qū)問題,有一個節(jié)點(diǎn)通信故障,寫請求寫不過去,因此只有兩個節(jié)點(diǎn)包含了值為 20 的數(shù)據(jù)。
此時(shí),寫請求會返回給客戶端一個結(jié)果,可能會告訴客戶端寫入成功了,也可能告訴客戶端寫入部分成功。
這時(shí)候,當(dāng)后續(xù)的讀請求恰巧被發(fā)送到有通信故障的那個節(jié)點(diǎn),系統(tǒng)可能只能返回一個空的結(jié)果。但是,由于系統(tǒng)處理和返回了讀寫請求,所以,系統(tǒng)是滿足了 CAP 中的可用性的。
疑問二:數(shù)據(jù)分片和數(shù)據(jù)副本的分布式系統(tǒng)是否都遵守 CAP 定理
我們知道,在一套大規(guī)模的分布式系統(tǒng)里,一定是既需要把海量數(shù)據(jù)做切分,存儲到不同的機(jī)器上,也需要對這些存儲了數(shù)據(jù)的機(jī)器做副本備份的。
那么,如果,一個分布式系統(tǒng)里只有數(shù)據(jù)分片存儲或者只有數(shù)據(jù)副本存儲,他們都會遵守 CAP 定理嗎?
答案是當(dāng)數(shù)據(jù)分片時(shí),也是要遵守 CAP 定理,但是,是種非常特殊的遵守。
當(dāng)在一套分布式系統(tǒng)只有分片存儲的時(shí)候,CAP 理論會表現(xiàn)成什么樣?
比如,我們有個分布式系統(tǒng),由三個節(jié)點(diǎn) a、b、c 組成。其中節(jié)點(diǎn) a 存放了 A 表的數(shù)據(jù),b 存放了 B 表的數(shù)據(jù),c 存放了 C 表的數(shù)據(jù)。
如果有一個業(yè)務(wù),它的意圖是想往 A 表插入一條新數(shù)據(jù),在 B 表刪除一條已有數(shù)據(jù),在 C 表更新一條老數(shù)據(jù),這個分布式系統(tǒng)該怎么處理這種業(yè)務(wù)?
技術(shù)上我們對這種一個意圖想做多件事的情況往往會包裝成一個事務(wù)。當(dāng)我們包裝成一個事務(wù)以后,我們可能會通過先在 a 節(jié)點(diǎn)執(zhí)行,然后去 b 節(jié)點(diǎn)執(zhí)行,最后去 c 節(jié)點(diǎn)執(zhí)行,等到都成功了,才會返回成功。
但是,發(fā)生了分區(qū)以后怎么辦?當(dāng)在 a、b 節(jié)點(diǎn)都成功了,到 c 發(fā)現(xiàn)發(fā)生了通信故障?
此時(shí),根據(jù) CAP 定理,你有兩個選擇,要么就直接返回一個部分成功的結(jié)果給客戶端,要么直接卡死等客戶端超時(shí)或者返回失敗給客戶端。當(dāng)返回部分成功的時(shí)候,這就是選擇了可用性(A),當(dāng)卡死或者返回失敗給客戶端的時(shí)候,就是選擇了一致性(C)。
可是,我們將請求包裝成了事務(wù),而事務(wù)是要求要么都成功,要么都失敗……為了遵守這種要求,對于分布式只有分片的情況,迫于客觀條件,只能選擇C。所以分片的分布式系統(tǒng),往往都是 CP 的系統(tǒng)。
可選擇,但是無法選擇是分布式系統(tǒng)只有分片數(shù)據(jù)存儲的情況時(shí),遵守 CAP 定理的特殊表現(xiàn)。
而當(dāng)分布式系統(tǒng)是多個節(jié)點(diǎn),每個節(jié)點(diǎn)存儲了完整的一套數(shù)據(jù),別的節(jié)點(diǎn)只是完整數(shù)據(jù)的備份的時(shí)候,即使事務(wù)只在一臺機(jī)器上成功,當(dāng)發(fā)生分區(qū)故障的時(shí)候,我們也是可以有充分的余地選擇是單機(jī)事務(wù)的回退 or 就此認(rèn)為寫成功的。
單機(jī)事務(wù)的回退,就可以對外表現(xiàn)為選擇了一致性。
就此認(rèn)為寫成功,則可以認(rèn)為選擇了可用性。
疑問三:為何有時(shí)候區(qū)分一個系統(tǒng)是 AP 還是 CP 是如此之難
因?yàn)?,就像我們前面講過的,由于 AP 或者 CP 的選擇,可能僅局限為整套系統(tǒng)的局部,甚至某些特殊的數(shù)據(jù)上,而我們又是用這種局部的特性去描述了整套系統(tǒng),所以就導(dǎo)致了區(qū)分的困難。而這本身其實(shí)也日漸成為了 CAP 的一個大問題,從而被人詬病。
6. CAP 的不足
-
CAP 定理本身是沒有考慮網(wǎng)絡(luò)延遲的問題的,它認(rèn)為一致性是立即生效的,但是,要保持一致性,是需要時(shí)間成本的,這就導(dǎo)致往往分布式系統(tǒng)多選擇 AP 方式
-
由于時(shí)代的演變,CAP 定理在針對所有分布式系統(tǒng)的時(shí)候,出現(xiàn)了一些力不從心的情況,導(dǎo)致很多時(shí)候它自己會把以前很嚴(yán)謹(jǐn)?shù)臄?shù)學(xué)定義改成了比較松弛的業(yè)務(wù)定義,類似于我們看到,CAP 定理把一致性、可用性、分區(qū)容錯都變成了一個范圍屬性,而這和 CAP 定理本身這種數(shù)學(xué)定理般的稱呼是有沖突的,出現(xiàn)了不符合數(shù)學(xué)嚴(yán)謹(jǐn)定義的問題。
-
在實(shí)踐中以及后來 CAP 定理的提出者也承認(rèn),一致性和可用性并不僅僅是二選一的問題,只是一些重要性的區(qū)別,當(dāng)強(qiáng)調(diào)一致性的時(shí)候,并不表示可用性是完全不可用的狀態(tài)。比如,Zookeeper 只是在 master 出現(xiàn)問題的時(shí)候,才可能出現(xiàn)幾十秒的不可用狀態(tài),而別的時(shí)候,都會以各種方式保證系統(tǒng)的可用性。而強(qiáng)調(diào)可用性的時(shí)候,也往往會采用一些技術(shù)手段,去保證數(shù)據(jù)最終是一致的。CAP 定理并沒有給出這些情況的具體描述。
-
CAP 理論從工程角度來看只是一種狀態(tài)的描述,它告訴大家當(dāng)有錯的時(shí)候,分布式系統(tǒng)可能處在什么狀態(tài)。但是,狀態(tài)是可能變化的。狀態(tài)間如何轉(zhuǎn)換,如何修補(bǔ),如何恢復(fù)是沒有提供方向的。
7. 引申出來的 BASE
正因?yàn)?CAP 以上的種種不足,epay 的架構(gòu)師 Dan Pritchett 根據(jù)他自身在大規(guī)模分布式系統(tǒng)的實(shí)踐經(jīng)驗(yàn),總結(jié)出了 BASE 理論。BASE 理論是對 CAP 理論的延伸,核心思想是即使無法做到強(qiáng)一致性(Strong Consistency),但應(yīng)用可以采用適合的方式達(dá)到最終一致性(Eventual Consitency)。
BASE 理論是實(shí)踐工程的理論,它彌補(bǔ)了CAP 理論過于抽象的問題,也同時(shí)解決了 AP 系統(tǒng)的總體工程實(shí)踐思想,是分布式系統(tǒng)的核心理論之一,我們將在下一篇文章里,詳細(xì)的講解此套理論。
8. 大廠面試題
在文章最后,來幾道大廠關(guān)于 CAP 的面試真題,檢驗(yàn)一下你的學(xué)習(xí)效果,hiahiahia
-
什么是 CAP 理論?
-
CAP 中的 P 是什么意思?
-
為什么說分布式系統(tǒng),只能在 C、A 中二選一?
-
結(jié)合實(shí)際應(yīng)用,CP、AP 該怎么選擇?
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點(diǎn),不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!