溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

分布式系統(tǒng)知識分享:正確理解CAP定理

發(fā)布時間:2020-08-14 10:46:38 來源:ITPUB博客 閱讀:144 作者:HitTwice 欄目:軟件技術(shù)

  前言

  CAP的理解我也看了很多書籍,也看了不少同行的博文,基本每個人的理解都不一樣,而布魯爾教授得定義又太過的簡單,沒有具體描述和場景案例分析。因此自己參考部分資料梳理了一篇與大家互相分享一下。

  標(biāo)題寫了正確理解,或許某些點(diǎn)不是百分百正確或者有歧義,但是希望與各位分享討論后達(dá)到最終正確。

  簡介

  CAP定理,又被稱作布魯爾定理(Brewer's theorem),是埃里克·布魯爾教授在2000 年提出的一個猜想,它指出對于一個分布式系統(tǒng)來說,不可能同時滿足以下三點(diǎn):

  ·Consistency(一致性): where all nodes see the same data at the same time.(所有節(jié)點(diǎn)在同一時間具有相同的數(shù)據(jù))

  ·Availability(可用性): which guarantees that every request receives a response about whether it succeeded or failed.(保證每個請求不管成功或者失敗都有響應(yīng))

  ·Partition tolerance(分隔容忍): where the system continues to operate even if any one part of the system is lost or fails.(系統(tǒng)中任意信息的丟失或失敗不會影響系統(tǒng)的繼續(xù)運(yùn)作)

  很多書籍與文章引用Robert Greiner在2014年8月寫的一篇博文 http://robertgreiner.com/2014/08/cap-theorem-revisited/。相比與看著布魯爾教授一臉懵逼的定義,Robert Greiner的更加容易理解。

  定義

  原文:In a distributed system (a collection of interconnected nodes that share data.), you can only have two out of the following three guarantees across a write/read pair: Consistency, Availability, and Partition Tolerance - one of them must be sacrificed.

  翻譯:在一個分布式系統(tǒng)(指互相連接并共享數(shù)據(jù)的節(jié)點(diǎn)的集合)中,當(dāng)涉及讀寫操作時,只能保證一致性(Consistence)、可用性(Availability)、分區(qū)容錯性(Partition Tolerance)三者中的兩個,另外一個必須被犧牲。

  關(guān)鍵字:interconnected nodes(互連節(jié)點(diǎn))、share data(共享數(shù)據(jù))、a write/read pair(讀/寫)

  從上面一段話,有幾個,也就是說我們聊CAP定理的時候,是在具有數(shù)據(jù)讀寫、數(shù)據(jù)共享和節(jié)點(diǎn)互連的前提下,對上面三者選其二,也是建議我們不要花費(fèi)時間與精力同時滿足三者。

  舉例說明,web集群、memcached集群不屬于討論對象

  web集群只是資源復(fù)制分配在不同的節(jié)點(diǎn)上,然而節(jié)點(diǎn)間沒有互連、也沒有數(shù)據(jù)共享(sessionid、memory cache)。

  memcached集群數(shù)據(jù)存儲是通過客戶端實現(xiàn)哈希一致性,但是集群節(jié)點(diǎn)間不互連的,也沒有數(shù)據(jù)共享。

  總得來說,CAP定理討論的并不是分布式系統(tǒng)所有的功能。

  一致性(Consistency)

  原文:A read is guaranteed to return the most recent write for a given client.

  翻譯:對某個指定的客戶端來說,讀操作保證能夠返回最新的寫操作結(jié)果

  關(guān)鍵字:a given client(指定的客戶端)。

  這里的一致性與我們平常了解ACID的一致性有點(diǎn)偏差,ACID的一致性關(guān)注的是數(shù)據(jù)庫的數(shù)據(jù)完整性。

  上面定義沒說明是所有節(jié)點(diǎn)必須在同一時間數(shù)據(jù)一致,而關(guān)注點(diǎn)在客戶端,假如有個場景,您在ATM(客戶端)往某張銀行卡存500元后,立刻在ATM發(fā)起查詢余額的時候會顯示加了500元后的余額,隨后我們也能把這500元取出來。查詢余額讀操作可以是寫后立刻讀的主庫,也或者寫后某個時間段過后(中途無寫)讀從庫。

  可用性(Availability)

  原文:A non-failing node will return a reasonable response within a reasonable amount of time (no error or timeout).

  翻譯:非故障節(jié)點(diǎn)將在合理的時間內(nèi)返回合理的響應(yīng)(不是錯誤或超時)。

  關(guān)鍵字:non-failing node(非故障節(jié)點(diǎn))、reasonable response(合理的響應(yīng))

  這里的可用性和我們平常所理解的高可用性有點(diǎn)偏差,高可用性指系統(tǒng)無中斷的執(zhí)行其功能的能力。

  已故障的節(jié)點(diǎn)就不具有可用性了,因為請求結(jié)果要么error要么 timeout。合理的響應(yīng)沒有說明是成功還是失敗,但是響應(yīng)應(yīng)該具有是否成功的精確描述。例如我們讀取sql server集群的某從庫,同步需要時間,讀取出來可能不是最新的數(shù)據(jù),但卻是合理的響應(yīng)。

  分區(qū)容錯性(Partition tolerance)

  原文:The system will continue to function when network partitions occur.

  翻譯:當(dāng)網(wǎng)絡(luò)分區(qū)發(fā)生時,系統(tǒng)將繼續(xù)正常運(yùn)作

  關(guān)鍵字:continue to function(繼續(xù)正常運(yùn)作)

  假如做了一個redis的一主兩從的集群,某天某個從節(jié)點(diǎn)因為網(wǎng)絡(luò)故障變成不可用,但是另外的一主一 從仍然能正常運(yùn)作,那么我們認(rèn)為它具有分區(qū)容錯性。

  CA-犧牲分區(qū)容錯性

  作為分布式系統(tǒng),分區(qū)必然總會發(fā)生(2年1次50分鐘還是1年3次共10分鐘?),因此認(rèn)為CAP的討論是大部分建立在P確立前提下。假設(shè)我們犧牲了P這個時候因為網(wǎng)絡(luò)故障發(fā)生了分區(qū)導(dǎo)致節(jié)點(diǎn)不可用,這個時候請求響應(yīng)了error、timeout,與可用性的定義相沖突了。

  但是,我們又假如分區(qū)大部分時間是不存在的,這時對單節(jié)點(diǎn)的讀\寫,那么就無需作出C、A的取舍。但是上面說分區(qū)總會發(fā)生這不互相矛盾么,還是取舍。假如1年時間內(nèi)99.99%時間是正常的,不可用時間為0.01%(52.56分鐘)不可用,若這個時間屬于業(yè)務(wù)接受范圍,或者只在某個地區(qū)(華南、華北、華中?)有影響,那么CA也是可以選擇的。

  PC-犧牲可用性

  最典型的案例是RDBMS集群與Redis集群,這兩種都是利用主從復(fù)制實現(xiàn)讀寫分離的方案。假如兩者都是建立一主多從的集群,在主節(jié)點(diǎn)寫入數(shù)據(jù),為了保證隨后的讀操作獲取最新數(shù)據(jù)(一致性),這個讀操作仍會請求主節(jié)點(diǎn)(讀寫分離的復(fù)雜點(diǎn)在從庫同步不及時導(dǎo)致業(yè)務(wù)的異常,為了保證業(yè)務(wù)的正常性寫后的讀會請求主庫),某個從節(jié)點(diǎn)掛了但是只要主節(jié)點(diǎn)和其他從節(jié)點(diǎn)仍然正常運(yùn)作,就滿足分區(qū)容錯性。但是哪天主節(jié)點(diǎn)因為網(wǎng)絡(luò)故障導(dǎo)致寫操作的error或者timeout,那么這個系統(tǒng)就不可用了(犧牲可用性)。

  這個時候可以引入其他功能和機(jī)制完成,例如Redis哨兵模式、故障轉(zhuǎn)移功能。

  PA-犧牲一致性

  最典型的案例是Cassanda集群和Riak集群,這種類型的分布式數(shù)據(jù)庫,可以任意節(jié)點(diǎn)寫入,任意節(jié)點(diǎn)讀取,當(dāng)作為集群出現(xiàn),無論寫入哪個節(jié)點(diǎn),都將會把該節(jié)點(diǎn)的數(shù)據(jù)同步到其他節(jié)點(diǎn)上,因為這種同步方式,讀取數(shù)據(jù)時只要訪問一個節(jié)點(diǎn)就足夠了(喜歡任意訪問也不攔著你),但是因為其他節(jié)點(diǎn)數(shù)據(jù)同步原因,數(shù)據(jù)可能并不是最新的(犧牲一致性)。如果當(dāng)前節(jié)點(diǎn)因為網(wǎng)絡(luò)異常導(dǎo)致分區(qū)變得不可用(無論讀\寫),可以轉(zhuǎn)移訪問節(jié)點(diǎn)(可用性)。

  另外這里說的犧牲一致性,并不代表放棄一致性,而PA選擇的是最終一致性(系統(tǒng)中所有的數(shù)據(jù)副本,在經(jīng)過一段時間的同步后,最終能夠達(dá)到一個一致的狀態(tài))

  總結(jié)

  上面涉及“犧牲”字眼,并不代表非此即彼的選擇,可以根據(jù)子系統(tǒng)、模塊之間的設(shè)計上進(jìn)行混搭使用(例如PA和PC、CA和PC)。

  本文對CAP定理做了一個簡單的梳理描述,參考了部分書籍和文章加上自己的理解希望可以跟大家做個分享,如果有不同建議和看法包括文章內(nèi)描述錯誤,請在下方評論指出,我將及時作出修改。

  作 者: 陳珙

  出 處:http://www.cnblogs.com/skychen1218/ 

  關(guān)于作者:專注于微軟平臺的項目開發(fā)。如有問題或建議,請多多賜教! 

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI