天天看點

分布式CAP定理,為什麼不能同時滿足三個特性一、CAP的定義三、總結

在弄清楚這個問題之前,我們先了解一下什麼是分布式的CAP定理。

根據百度百科的定義,CAP定理又稱CAP原則,指的是在一個分布式系統中,Consistency(一緻性)、 Availability(可用性)、Partition tolerance(分區容錯性),最多隻能同時三個特性中的兩個,三者不可兼得。

一、CAP的定義

Consistency (一緻性):

“all nodes see the same data at the same time”,即更新操作成功并傳回用戶端後,所有節點在同一時間的資料完全一緻,這就是分布式的一緻性。一緻性的問題在并發系統中不可避免,對于用戶端來說,一緻性指的是并發通路時更新過的資料如何擷取的問題。從服務端來看,則是更新如何複制分布到整個系統,以保證資料最終一緻。

Availability (可用性):

可用性指“Reads and writes always succeed”,即服務一直可用,而且是正常響應時間。好的可用性主要是指系統能夠很好的為使用者服務,不出現使用者操作失敗或者通路逾時等使用者體驗不好的情況。

Partition Tolerance (分區容錯性):

即分布式系統在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一緻性和可用性的服務。

分區容錯性要求能夠使應用雖然是一個分布式系統,而看上去卻好像是在一個可以運轉正常的整體。比如現在的分布式系統中有某一個或者幾個機器宕掉了,其他剩下的機器還能夠正常運轉滿足系統需求,對于使用者而言并沒有什麼體驗上的影響。

二、CAP定理的證明

現在我們就來證明一下,為什麼不能同時滿足三個特性?

假設有兩台伺服器,一台放着應用A和資料庫V,一台放着應用B和資料庫V,他們之間的網絡可以互通,也就相當于分布式系統的兩個部分。

在滿足一緻性的時候,兩台伺服器(假設為N1,N2)的資料是一樣的,DB0=DB0。在滿足可用性的時候,使用者不管是請求N1或者N2,都會得到立即響應。在滿足分區容錯性的情況下,N1和N2有任何一方當機,或者網絡不通的時候,都不會影響N1和N2彼此之間的正常運作。

分布式CAP定理,為什麼不能同時滿足三個特性一、CAP的定義三、總結

圖一中,使用者通過N1中的A應用請求資料更新到伺服器DB0,這時N1中的伺服器DB0變為DB1,通過分布式系統的資料同步更新操作,N2伺服器中的資料庫V0也更新為了DB1,這時,使用者通過B向資料庫發起請求得到的資料就是即時更新後的資料DB1。

上面是正常運作的情況,但分布式系統中,最大的問題就是網絡,現在假設一種極端情況,N1和N2之間的網絡斷開了,但我們仍要支援這種網絡異常,也就是滿足分區容錯性,那麼這樣能不能同時滿足一緻性和可用性呢?

分布式CAP定理,為什麼不能同時滿足三個特性一、CAP的定義三、總結

假設N1和N2之間通信的時候網絡突然出現故障,有使用者向N1發送資料更新請求,那N1中的資料DB0将被更新為DB1,由于網絡是斷開的,N2中的資料庫仍舊是DB0;

如果這個時候,有使用者向N2發送資料讀取請求,由于資料還沒有進行同步,應用程式沒辦法立即給使用者傳回最新的資料DB1,怎麼辦呢?有二種選擇,第一,犧牲資料一緻性,響應舊的資料DB0給使用者;第二,犧牲可用性,阻塞等待,直到網絡連接配接恢複,資料更新操作完成之後,再給使用者響應最新的資料DB1。

上面的過程是比較簡單 (鑒于樓主作圖水準實在太渣,希望各位勿噴,哈哈吐舌頭) ,但也說明了要滿足分區容錯性的分布式系統,隻能在一緻性和可用性兩者中,選擇其中一個。也就是說分布式系統不可能同時滿足三個特性。這就需要我們在搭建系統時進行取舍了,那麼,怎麼取舍才是更好的政策呢?

CA without P:如果不要求P(不允許分區),則C(強一緻性)和A(可用性)是可以保證的。但放棄P的同時也就意味着放棄了系統的擴充性,也就是分布式節點受限,沒辦法部署子節點,這是違背分布式系統設計的初衷的。

CP without A:如果不要求A(可用),相當于每個請求都需要在Server之間強一緻,而P(分區)會導緻同步時間無限延長(也就是等待資料同步完才能正常通路服務),如此CP也是可以保證的。很多傳統的資料庫分布式事務都屬于這種模式。

AP wihtout C:要高可用并允許分區,則需放棄一緻性。一旦分區發生,節點之間可能會失去聯系,為了高可用,每個節點隻能用本地資料提供服務,而這樣會導緻全局資料的不一緻性。現在衆多的NoSQL都屬于此類,如redis,mongdb等。

三、總結

現如今,對于多數大型網際網路應用的場景,主機衆多、部署分散,而且現在的叢集規模越來越大,節點隻會越來越多,是以節點故障、網絡故障是常态,是以分區容錯性也就成為了一個分布式系統必然要面對的問題。那麼就隻能在C和A之間進行取舍。但對于傳統的項目就可能有所不同,拿銀行的轉賬系統來說,涉及到金錢的對于資料一緻性不能做出一絲的讓步,C必須保證,出現網絡故障的話,甯可停止服務,可以在A和P之間做取舍。

總而言之,沒有最好的政策,好的系統應該是根據業務場景來進行架構設計的,隻有适合的才是最好的。

出處