CAP定理指的是在一個分布式系統(tǒng)中泞遗,Consistency(一致性)贡必、 Availability(可用性)、Partition tolerance(分區(qū)容錯性)匙握,最多只能同時三個特性中的兩個囚枪,三者不可兼得派诬。
一劳淆、CAP的定義
Consistency (一致性):
“all nodes see the same data at the same time”,即更新操作成功并返回客戶端后链沼,所有節(jié)點在同一時間的數(shù)據(jù)完全一致,這就是分布式的一致性沛鸵。一致性的問題在并發(fā)系統(tǒng)中不可避免括勺,對于客戶端來說,一致性指的是并發(fā)訪問時更新過的數(shù)據(jù)如何獲取的問題曲掰。從服務(wù)端來看疾捍,則是更新如何復(fù)制分布到整個系統(tǒng),以保證數(shù)據(jù)最終一致栏妖。比較典型的數(shù)據(jù)不一致情況是乱豆,如果對第一個節(jié)點的數(shù)據(jù)進行了更新,卻沒有使得第二個節(jié)點上的數(shù)據(jù)得到相應(yīng)的更新吊趾,于是客戶端在讀取第二個節(jié)點數(shù)據(jù)時依然是老數(shù)據(jù)宛裕。
Availability (可用性):
可用性指“Reads and writes always succeed”,即服務(wù)一直可用论泛,而且是正常響應(yīng)時間揩尸。好的可用性主要是指系統(tǒng)能夠很好的為用戶服務(wù),不出現(xiàn)用戶操作失敗或者訪問超時等用戶體驗不好的情況屁奏。對于用戶的每一個操作都能夠在有限的時間內(nèi)返回結(jié)果岩榆。
Partition Tolerance (分區(qū)容錯性):
即分布式系統(tǒng)在遇到某節(jié)點或網(wǎng)絡(luò)分區(qū)故障的時候,仍然能夠?qū)ν馓峁M足一致性和可用性的服務(wù)坟瓢。
分區(qū)容錯性要求能夠使應(yīng)用雖然是一個分布式系統(tǒng)勇边,而看上去卻好像是在一個可以運轉(zhuǎn)正常的整體。比如現(xiàn)在的分布式系統(tǒng)中有某一個或者幾個機器宕掉了折联,其他剩下的機器還能夠正常運轉(zhuǎn)滿足系統(tǒng)需求粒褒,對于用戶而言并沒有什么體驗上的影響。
二崭庸、CAP定理的證明
現(xiàn)在我們就來證明一下怀浆,為什么不能同時滿足三個特性谊囚?
假設(shè)有兩臺服務(wù)器,一臺放著應(yīng)用A和數(shù)據(jù)庫V执赡,一臺放著應(yīng)用B和數(shù)據(jù)庫V镰踏,他們之間的網(wǎng)絡(luò)可以互通,也就相當(dāng)于分布式系統(tǒng)的兩個部分沙合。
在滿足一致性的時候奠伪,兩臺服務(wù)器 N1和N2,一開始兩臺服務(wù)器的數(shù)據(jù)是一樣的首懈,DB0=DB0绊率。在滿足可用性的時候,用戶不管是請求N1或者N2究履,都會得到立即響應(yīng)滤否。在滿足分區(qū)容錯性的情況下,N1和N2有任何一方宕機最仑,或者網(wǎng)絡(luò)不通的時候藐俺,都不會影響N1和N2彼此之間的正常運作。? ? ??? ?
當(dāng)用戶通過N1中的A應(yīng)用請求數(shù)據(jù)更新到服務(wù)器DB0后泥彤,這時N1中的服務(wù)器DB0變?yōu)镈B1欲芹,通過分布式系統(tǒng)的數(shù)據(jù)同步更新操作,N2服務(wù)器中的數(shù)據(jù)庫V0也更新為了DB1吟吝,這時菱父,用戶通過B向數(shù)據(jù)庫發(fā)起請求得到的數(shù)據(jù)就是即時更新后的數(shù)據(jù)DB1。
上面是正常運作的情況剑逃,但分布式系統(tǒng)中浙宜,最大的問題就是網(wǎng)絡(luò)傳輸問題,現(xiàn)在假設(shè)一種極端情況炕贵,N1和N2之間的網(wǎng)絡(luò)斷開了梆奈,但我們?nèi)砸С诌@種網(wǎng)絡(luò)異常,也就是滿足分區(qū)容錯性称开,那么這樣能不能同時滿足一致性和可用性呢亩钟?
假設(shè)N1和N2之間通信的時候網(wǎng)絡(luò)突然出現(xiàn)故障,有用戶向N1發(fā)送數(shù)據(jù)更新請求鳖轰,那N1中的數(shù)據(jù)DB0將被更新為DB1清酥,由于網(wǎng)絡(luò)是斷開的,N2中的數(shù)據(jù)庫仍舊是DB0蕴侣;
如果這個時候焰轻,有用戶向N2發(fā)送數(shù)據(jù)讀取請求,由于數(shù)據(jù)還沒有進行同步昆雀,應(yīng)用程序沒辦法立即給用戶返回最新的數(shù)據(jù)DB1辱志,怎么辦呢蝠筑?有二種選擇,第一揩懒,犧牲數(shù)據(jù)一致性什乙,響應(yīng)舊的數(shù)據(jù)DB0給用戶;第二已球,犧牲可用性臣镣,阻塞等待,直到網(wǎng)絡(luò)連接恢復(fù)智亮,數(shù)據(jù)更新操作完成之后忆某,再給用戶響應(yīng)最新的數(shù)據(jù)DB1。
上面的過程比較簡單阔蛉,但也說明了要滿足分區(qū)容錯性的分布式系統(tǒng)弃舒,只能在一致性和可用性兩者中,選擇其中一個馍忽。也就是說分布式系統(tǒng)不可能同時滿足三個特性棒坏。這就需要我們在搭建系統(tǒng)時進行取舍了,那么遭笋,怎么取舍才是更好的策略呢?
三、取舍策略
CAP三個特性只能滿足其中兩個徒探,那么取舍的策略就共有三種:
CA without P:如果不要求P(不允許分區(qū))瓦呼,則C(強一致性)和A(可用性)是可以保證的。但放棄P的同時也就意味著放棄了系統(tǒng)的擴展性测暗,也就是分布式節(jié)點受限央串,沒辦法部署子節(jié)點,這是違背分布式系統(tǒng)設(shè)計的初衷的碗啄。典型的協(xié)議比如“兩階段提交”(2PC)质和。
CP without A:如果不要求A(可用),相當(dāng)于每個請求都需要在服務(wù)器之間保持強一致稚字,而P(分區(qū))會導(dǎo)致同步時間無限延長(也就是等待數(shù)據(jù)同步完才能正常訪問服務(wù))饲宿,一旦發(fā)生網(wǎng)絡(luò)故障或者消息丟失等情況,就要犧牲用戶的體驗胆描,等待所有數(shù)據(jù)全部一致了之后再讓用戶訪問系統(tǒng)瘫想。設(shè)計成CP的系統(tǒng)其實不少,最典型的就是分布式數(shù)據(jù)庫昌讲,如Redis国夜、HBase、銀行交易系統(tǒng)等短绸。對于這些分布式數(shù)據(jù)庫來說车吹,數(shù)據(jù)的一致性是最基本的要求筹裕,因為如果連這個標(biāo)準(zhǔn)都達不到,那么直接采用關(guān)系型數(shù)據(jù)庫就好窄驹,沒必要再浪費資源來部署分布式數(shù)據(jù)庫饶碘。典型的協(xié)議比如Paxos算法。
?AP wihtout C:要高可用并允許分區(qū)馒吴,則需放棄一致性扎运。一旦分區(qū)發(fā)生,節(jié)點之間可能會失去聯(lián)系饮戳,為了高可用豪治,每個節(jié)點只能用本地數(shù)據(jù)提供服務(wù),而這樣會導(dǎo)致全局數(shù)據(jù)的不一致性扯罐。典型的應(yīng)用就如某米的搶購手機場景负拟,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當(dāng)你選擇完商品準(zhǔn)備下單的時候歹河,系統(tǒng)提示你下單失敗掩浙,商品已售完。這其實就是先在 A(可用性)方面保證系統(tǒng)可以正常的服務(wù)秸歧,然后在數(shù)據(jù)的一致性方面做了些犧牲厨姚,雖然多少會影響一些用戶體驗,但也不至于造成用戶購物流程的嚴(yán)重阻塞键菱。
四谬墙、總結(jié)
現(xiàn)如今,對于多數(shù)大型互聯(lián)網(wǎng)應(yīng)用的場景经备,主機眾多拭抬、部署分散,而且現(xiàn)在的集群規(guī)模越來越大侵蒙,節(jié)點只會越來越多造虎,所以節(jié)點故障、網(wǎng)絡(luò)故障是常態(tài)纷闺,因此分區(qū)容錯性也就成為了一個分布式系統(tǒng)必然要面對的問題算凿。那么就只能在C和A之間進行取舍。但對于傳統(tǒng)的項目就可能有所不同急但,拿銀行的轉(zhuǎn)賬系統(tǒng)來說澎媒,涉及到金錢的對于數(shù)據(jù)一致性不能做出一絲的讓步,C必須保證波桩,出現(xiàn)網(wǎng)絡(luò)故障的話戒努,寧可停止服務(wù),可以在A和P之間做取舍。
總而言之储玫,沒有最好的策略侍筛,好的系統(tǒng)應(yīng)該是根據(jù)業(yè)務(wù)場景來進行架構(gòu)設(shè)計的,只有適合的才是最好的撒穷。