新聞中心
大家好,歡迎來(lái)到Tlog4J課堂,我是Jensen。

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序定制開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了永年免費(fèi)建站歡迎大家使用!
分布式CAP定理大家也耳熟能詳了,CAP指的是分布式系統(tǒng)中的三個(gè)特性:
在我之前的文章也有提到過(guò)——CAP是分布式系統(tǒng)中三個(gè)維度的“客戶承諾”:
- 一致性(Consistency):要么我給你返回一個(gè)錯(cuò)誤,要么我給你返回絕對(duì)一致的最新數(shù)據(jù),強(qiáng)調(diào)數(shù)據(jù)正確。
- 可用性(Availibility):我一定會(huì)給你返回?cái)?shù)據(jù),不會(huì)給你返回錯(cuò)誤,但不保證數(shù)據(jù)最新,強(qiáng)調(diào)的是服務(wù)不出錯(cuò)。
- 分區(qū)容錯(cuò)性(Partition Tolerance):我會(huì)一直運(yùn)行,不管我的內(nèi)部出現(xiàn)何種數(shù)據(jù)同步問(wèn)題,強(qiáng)調(diào)的是不掛掉。
在Jeff Hodges精彩的博文筆記中,他建議我們用 CAP 定理來(lái)評(píng)論分布式系統(tǒng),并且很多人都聽取了這個(gè)建議,描述他們的系統(tǒng)為“CP” (有一致性但在網(wǎng)絡(luò)分區(qū)的時(shí)候不可用),“AP”(可用但是在網(wǎng)絡(luò)分區(qū)的時(shí)候不一致) 或者有時(shí)候 “CA”。
那這次咱們?cè)偕钊胩接懸幌?,不同的系統(tǒng)按CP/AP來(lái)劃分,到底合不合理。
回過(guò)頭來(lái)看一致性
首先我們要了解,數(shù)據(jù)的一致性問(wèn)題存在于計(jì)算機(jī)軟硬件層面的任意一個(gè)數(shù)據(jù)拷貝的環(huán)節(jié),如CPU與內(nèi)存的數(shù)據(jù)拷貝、內(nèi)存間的數(shù)據(jù)拷貝、內(nèi)存與磁盤的數(shù)據(jù)拷貝、計(jì)算機(jī)之間的網(wǎng)絡(luò)通訊等等。
而分布式系統(tǒng)是基于軟件系統(tǒng)的,系統(tǒng)分布在不同的計(jì)算機(jī)必然會(huì)產(chǎn)生網(wǎng)絡(luò)通訊延遲或網(wǎng)絡(luò)分區(qū)的情況,以我們現(xiàn)在的計(jì)算機(jī)技術(shù)是無(wú)法100%解決一致性問(wèn)題的。
CAP中的一致性是可線性化的意思,它是非常特殊、非常強(qiáng)的一致性,雖然說(shuō)ACID中的C也是一致性,但和CAP的一致性沒(méi)有任何關(guān)系。
那什么是可線性化呢?
舉個(gè)例子:如果B操作在完成A操作成功之后,那么整個(gè)系統(tǒng)對(duì)B操作來(lái)說(shuō)必須表現(xiàn)為A操作已經(jīng)完成了或者更新的狀態(tài)。
這張圖展示了 Alice 還有 Bob, 他們?cè)谕粋€(gè)房間,都在用他們的手機(jī)查詢 2014 年世界杯的決賽結(jié)果。
就在最終結(jié)果剛發(fā)布之后,Alice 刷新了頁(yè)面,看到了宣布冠軍的消息,而且很興奮地告訴了 Bob。
Bob 馬上也重新加載了他手機(jī)上的頁(yè)面,但是他的請(qǐng)求被送到了一個(gè)數(shù)據(jù)庫(kù)的拷貝,還沒(méi)有拿到產(chǎn)生結(jié)果的數(shù)據(jù),結(jié)果他的手機(jī)上顯示決賽還正在進(jìn)行。
如果 Alice 和 Bob 同時(shí)刷新,拿到了不一樣的結(jié)果,并不會(huì)太讓人意外,因?yàn)樗麄儾恢谰唧w服務(wù)器到底是先處理了他們中哪一個(gè)請(qǐng)求。
但是 Bob 知道他刷新頁(yè)面是在 Alice 告訴了他最終結(jié)果之后的,所以他預(yù)期他查詢的結(jié)果一定比 Alice 的更新,但事實(shí)是他卻拿到了舊的結(jié)果,這就違反了可線性化。
只有 Bob 通過(guò)另外一個(gè)溝通渠道從 Alice 那里知道了結(jié)果, Bob 才能知道他的請(qǐng)求一定在 Alice 之后。
如果 Bob 沒(méi)有從 Alice 那里聽到比賽已經(jīng)結(jié)束了,他就不會(huì)知道他看到的結(jié)果是舊的。
如果你在建一個(gè)數(shù)據(jù)庫(kù),你不知道用戶們會(huì)有什么另外的溝通渠道,所以,如果你想提供可線性化訪問(wèn),你就需要讓你的數(shù)據(jù)庫(kù)看起來(lái)就好像只有一個(gè)拷貝,雖然實(shí)際上可能有多個(gè)備份在多個(gè)地方。
這是一個(gè)非常昂貴的屬性,因?yàn)樗竽阕龊芏鄥f(xié)調(diào)工作,甚至你電腦上的CPU都不提供本地內(nèi)存的可線性化訪問(wèn)!
在現(xiàn)代的CPU上,你需要用Memory Barrier指令來(lái)達(dá)到可線性化訪問(wèn),甚至測(cè)試一個(gè)系統(tǒng)是不是可線性化的也是非常困難的。
所以說(shuō),脫離了關(guān)注點(diǎn),討論一致性沒(méi)有多大意義。
回過(guò)頭來(lái)看可用性
可用性在CAP中是定義為“每一個(gè)請(qǐng)求如果被一個(gè)工作中的[數(shù)據(jù)庫(kù)]節(jié)點(diǎn)收到,那一定要返回[非錯(cuò)誤的]結(jié)果”。
注意到,這里一部分節(jié)點(diǎn)可以處理這個(gè)請(qǐng)求是不充分的,任意一個(gè)工作中的節(jié)點(diǎn)都要可以處理這個(gè)請(qǐng)求,所以很多自稱高可用的系統(tǒng)通常并沒(méi)有滿足這里的可用性的定義,它們只是做了故障轉(zhuǎn)移或者是熔斷降級(jí)而已。
CAP中根本沒(méi)有提到延遲,而我們其實(shí)對(duì)延遲比可用性更關(guān)心,事實(shí)上,滿足CAP可用性的系統(tǒng)可以花任意長(zhǎng)的時(shí)間來(lái)回復(fù)一個(gè)請(qǐng)求,而且同時(shí)保持可用性這個(gè)屬性。
但如果你的系統(tǒng)要花兩分鐘來(lái)加載一個(gè)頁(yè)面,你的用戶絕對(duì)不會(huì)認(rèn)為它是“可用的”,這也是為什么現(xiàn)在互聯(lián)網(wǎng)項(xiàng)目大多只允許2~10秒的請(qǐng)求延遲。
CP和AP的取舍
CAP定理只考慮了網(wǎng)絡(luò)分區(qū)這一種故障情況(比如所有節(jié)點(diǎn)還在運(yùn)行,但是他們之間的網(wǎng)絡(luò)已經(jīng)不工作了),這種故障絕對(duì)會(huì)發(fā)生,但是這不是唯一會(huì)出故障的地方。
節(jié)點(diǎn)可以整個(gè)崩潰或者重啟,你可能沒(méi)有足夠的磁盤空間,你可能會(huì)遇到一個(gè)軟件故障(bug),等等,在建分布式系統(tǒng)的時(shí)候,你需要考慮到更多得多的問(wèn)題,如果太關(guān)注CAP就容易導(dǎo)致忽略了其他重要的問(wèn)題。
那為什么在網(wǎng)絡(luò)分區(qū)的情況下,我們要放棄可用性和一致性中的一個(gè)呢?
舉個(gè)例子:你的數(shù)據(jù)庫(kù)有兩個(gè)拷貝在兩個(gè)不同的數(shù)據(jù)中心,具體怎么做備份并不重要,可以是Single-Master,或者多個(gè)Leader,或者基于Quorum的備份,要求是當(dāng)數(shù)據(jù)被寫到一個(gè)數(shù)據(jù)中心的時(shí)候,它也一定要被寫到另一個(gè)數(shù)據(jù)中心。
假設(shè)Client只連接到其中一個(gè)數(shù)據(jù)中心,而且連接兩個(gè)數(shù)據(jù)中心的網(wǎng)絡(luò)故障了,網(wǎng)絡(luò)中斷了就是我們所說(shuō)的網(wǎng)絡(luò)分區(qū)的意思,接下來(lái)會(huì)怎樣呢?
我們有兩個(gè)選擇:
- 應(yīng)用還是被允許寫到數(shù)據(jù)庫(kù),兩邊的數(shù)據(jù)庫(kù)還是完全可用的。但是一旦兩個(gè)數(shù)據(jù)庫(kù)之間的網(wǎng)絡(luò)中斷了,任何一個(gè)數(shù)據(jù)中心的寫操作就不會(huì)同步到另一個(gè)數(shù)據(jù)中心。這違反了可線性化(用之前的例子,Alice 可能鏈接到了一號(hào)數(shù)據(jù)中心,而 Bob 連接到了二號(hào)數(shù)據(jù)中心)。
- 如果你不想失去可線性化,就必須保證你的讀寫操作都在同一個(gè)數(shù)據(jù)中心,你可能叫它 Leader,另一個(gè)數(shù)據(jù)中心,因?yàn)榫W(wǎng)絡(luò)故障不能被更新,就必須停止接收讀寫操作,直到網(wǎng)絡(luò)恢復(fù),兩邊數(shù)據(jù)庫(kù)又進(jìn)行同步。所以雖然非Leader數(shù)據(jù)庫(kù)正常運(yùn)行,但是他卻不能處理請(qǐng)求,這就違反了 CAP 的可用性定義。
這個(gè)其實(shí)就是 CAP 定理的證明,咱們這里的例子用到了兩個(gè)數(shù)據(jù)中心,但對(duì)于一個(gè)數(shù)據(jù)中心內(nèi)的網(wǎng)絡(luò)故障也同樣適用,之所以這里用兩個(gè)數(shù)據(jù)中心是因?yàn)楦菀卓紤]這個(gè)問(wèn)題。
當(dāng)一個(gè)系統(tǒng)選擇了可線性化,也就是說(shuō)不是 CAP 可用的,并不意味著網(wǎng)絡(luò)分區(qū)一定會(huì)造成應(yīng)用停運(yùn)。
如果你可以把用戶的流量轉(zhuǎn)移到Leader數(shù)據(jù)庫(kù),那么用戶根本就不會(huì)注意到任何問(wèn)題。
實(shí)際應(yīng)用中的可用性和CAP可用性并不相同,咱們應(yīng)用的可用性多數(shù)是通過(guò)SLA來(lái)衡量的,比如99.9%正確的請(qǐng)求一定要在一秒鐘之內(nèi)返回成功,這實(shí)際上是一種整體的衡量。
但是一個(gè)系統(tǒng)無(wú)論是否滿足CAP可用性其實(shí)都可以滿足這樣的SLA,在實(shí)際操作中,跨多個(gè)數(shù)據(jù)中心的系統(tǒng)經(jīng)常是通過(guò)異步備份的,所以不是可線性化的。
但是做出這個(gè)選擇的原因經(jīng)常是因?yàn)檫h(yuǎn)距離網(wǎng)絡(luò)的延遲,而不是僅僅為了處理數(shù)據(jù)中心的網(wǎng)絡(luò)故障。
寫在最后
CAP定理其實(shí)是一個(gè)被簡(jiǎn)化了的理論,以致于被大眾廣泛地誤解了,實(shí)際上CAP是一個(gè)非常精確的定義。
其實(shí)大部分軟件都不在CP/AP這兩類中,但人們還是強(qiáng)行把軟件分為這兩類,這導(dǎo)致為了適用,不可避免地改變對(duì)“一致性”或者“可用性”的定義,如果用詞的定義改變了,CAP定理自己也不適用了,那CP/AP劃分也就完全沒(méi)有意義了。
所以,在技術(shù)面試的時(shí)候,我再也不會(huì)問(wèn)“哪些框架是CP的,哪些框架是AP的”這個(gè)問(wèn)題了,這么問(wèn)其實(shí)沒(méi)多大意義。
從另一方面看,CAP也是被廣泛接受的分布式基礎(chǔ)理論,很多框架也可以通過(guò)不同的配置實(shí)現(xiàn)廣義上的CP/AP,與其花時(shí)間跟別人解釋一堆按CP/AP來(lái)劃分系統(tǒng)是怎么不合理的,不如坦然接受現(xiàn)狀,但是別忘了,心中也要有自己的答案。
獨(dú)立思考,保持好奇心和耐心。
網(wǎng)頁(yè)題目:分布式的CP/AP是個(gè)偽二分法?
新聞來(lái)源:http://m.fisionsoft.com.cn/article/dhssdgc.html


咨詢
建站咨詢
