分佈式架構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。

上面的過程比較簡單,但也說明了要滿足分區容錯性的分佈式系統,只能在一致性和可用性兩者中,選擇其中一個。也就是說分佈式系統不可能同時滿足三個特性。這就需要我們在搭建系統時進行取捨了,那麼,怎麼取捨纔是更好的策略呢?

三、取捨策略
CAP三個特性只能滿足其中兩個,那麼取捨的策略就共有三種:

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

CP without A:如果不要求A(可用),相當於每個請求都需要在服務器之間保持強一致,而P(分區)會導致同步時間無限延長(也就是等待數據同步完才能正常訪問服務),一旦發生網絡故障或者消息丟失等情況,就要犧牲用戶的體驗,等待所有數據全部一致了之後再讓用戶訪問系統。設計成CP的系統其實不少,最典型的就是分佈式數據庫,如Redis、HBase等。對於這些分佈式數據庫來說,數據的一致性是最基本的要求,因爲如果連這個標準都達不到,那麼直接採用關係型數據庫就好,沒必要再浪費資源來部署分佈式數據庫。

AP wihtout C:要高可用並允許分區,則需放棄一致性。一旦分區發生,節點之間可能會失去聯繫,爲了高可用,每個節點只能用本地數據提供服務,而這樣會導致全局數據的不一致性。典型的應用就如某米的搶購手機場景,可能前幾秒你瀏覽商品的時候頁面提示是有庫存的,當你選擇完商品準備下單的時候,系統提示你下單失敗,商品已售完。這其實就是先在 A(可用性)方面保證系統可以正常的服務,然後在數據的一致性方面做了些犧牲,雖然多少會影響一些用戶體驗,但也不至於造成用戶購物流程的嚴重阻塞。

三、總結
現如今,對於多數大型互聯網應用的場景,主機衆多、部署分散,而且現在的集羣規模越來越大,節點只會越來越多,所以節點故障、網絡故障是常態,因此分區容錯性也就成爲了一個分佈式系統必然要面對的問題。那麼就只能在C和A之間進行取捨。但對於傳統的項目就可能有所不同,拿銀行的轉賬系統來說,涉及到金錢的對於數據一致性不能做出一絲的讓步,C必須保證,出現網絡故障的話,寧可停止服務,可以在A和P之間做取捨。

總而言之,沒有最好的策略,好的系統應該是根據業務場景來進行架構設計的,只有適合的纔是最好的。
————————————————
版權聲明:本文爲CSDN博主「鄙人薛某」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yeyazhishang/article/details/80758354

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章