分布式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彼此之間的正常運作。

                                              

                          (圖一)                                                                                   (圖二)

  

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

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

 

              

假設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之間做取舍。

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

有 0 個人打賞


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM