分佈式系統中的CAP理論,面試必問,你理解了嘛?


對於剛剛接觸分佈式系統的小夥伴們來說,一提起分佈式系統,就感覺高大上,深不可測。而且看了很多書和視頻還是一臉懵逼。這篇文章主要使用大白話的方式,帶你理解一下分佈式系統中的CAP理論。保證你能聽懂。

為了防止被誤以為是洗文的嫌疑,我在這裡先說明一下:我參考了知乎和博客園上等相關文章,還有下面的圖不是我自己畫的,我覺得能清晰地表達出意思就是好圖,在百度圖片上下載了一波。

一、什麼是分佈式系統

拿一個最簡單的例子,就比如說我們的圖書管理系統。之前的系統包含了所有的功能,比如用戶註冊登錄、管理員功能、圖書借閱管理等。這叫做集中式系統。也就是一個人幹了好幾件事。

後來隨著功能的增多,用戶量也越來越大。集中式系統維護太麻煩,拓展性也不好。於是就考慮著把這些功能分開。通俗的理解就是原本需要一個人乾的事,現在分給n個人幹,各自幹各自的,最終取得和一個人乾的效果一樣。

稍微正規一點的定義就是:一個業務分拆多個子業務,部署在不同的服務器上。 然後通過一定的通信協議,能夠讓這些子業務之間相互通信。

既然分給了n個人,那就涉及到這些人的溝通交流協作問題。想要去解決這些問題,就需要先聊聊分佈式系統中的CAP理論。千萬不要被這個看起來高大上的概念迷惑住。

二、簡單的概述一下

CAP理論指的是一個分佈式系統最多隻能同時滿足一致性(Consistency)、可用性(Availability)和分區容錯性(Partition tolerance)這三項中的兩項。拿一個網上的圖來看看。

分佈式系統中的CAP理論,面試必問,你理解了嘛?

這張圖不知道你之前看到過沒,如果你看過書或者是視頻,這張圖應該被列舉了好幾遍了。下面我不準備直接上來就對每一個特性進行概述。我們先從案例出發逐步過渡。

1、一個小例子

首先我們看一張圖。

分佈式系統中的CAP理論,面試必問,你理解了嘛?

現在網絡中有兩個節點N1和N2,他們之間網絡可以連通,N1中有一個應用程序A,和一個數據庫V,N2也有一個應用程序B2和一個數據庫V。現在,A和B是分佈式系統的兩個部分,V是分佈式系統的兩個子數據庫。

現在問題來了。突然有兩個用戶小明和小華分別同時訪問了N1和N2。我們理想中的操作是下面這樣的。

分佈式系統中的CAP理論,面試必問,你理解了嘛?

(1)小明訪問N1節點,小華訪問N2節點。同時訪問的。

(2)小明把N1節點的數據V0變成了V1。

(2)N1節點一看自己的數據有變化,立馬執行M操作,告訴了N2節點。

(4)小華讀取到的就是最新的數據。也是正確的數據。

上面這是一種最理想的情景。它滿足了CAP理論的三個特性。現在我們看看如何來理解滿足的這三個特性。

2、Consistency 一致性

一致性指的是所有節點在同一時間的數據完全一致。就好比剛剛舉得例子中,小明和小華讀取的都是正確的數據,對他們用戶來說,就好像是操作了同一個數據庫的同一個數據一樣。

因此對於一致性,也可以分為從客戶端和服務端兩個不同的視角來理解。

(1)客戶端

從客戶端來看,一致性主要指的是多併發訪問時更新過的數據如何獲取的問題。也就是小明和小華同時訪問,如何獲取更新的最新的數據。

(2)服務端

從服務端來看,則是更新如何分佈到整個系統,以保證數據最終一致。也就是N1節點和N2節點如何通信保持數據的一致。

對於一致性,一致的程度不同大體可以分為強、弱、最終一致性三類。

(1)強一致性

對於關係型數據庫,要求更新過的數據能被後續的訪問都能看到,這是強一致性。比如小明更新V0到V1,那麼小華讀取的時候也應該是V1。

(2)弱一致性

如果能容忍後續的部分或者全部訪問不到,則是弱一致性。比如小明更新VO到V1,可以容忍那麼小華讀取的時候是V0。

(3)最終一致性

如果經過一段時間後要求能訪問到更新後的數據,則是最終一致性。比如小明更新VO到V1,可以使得小華在一段時間之後讀取的時候是V0。

3、可用性

可用性指服務一直可用,而且是正常響應時間。就好比剛剛的N1和N2節點,不管什麼時候訪問,都可以正常的獲取數據值。而不會出現問題。好的可用性主要是指系統能夠很好的為用戶服務,不出現用戶操作失敗或者訪問超時等用戶體驗不好的情況。

對於可用性來說就比較好理解了。

4、分區容錯性

分區容錯性指在遇到某節點或網絡分區故障的時候,仍然能夠對外提供滿足一致性和可用性的服務。就好比是N1節點和N2節點出現故障,但是依然可以很好地對外提供服務。

這個分區容錯性也是很好理解。

在經過上面的分析中,在理想情況下,沒有出現任何錯誤的時候,這三條應該都是滿足的。但是天有不測風雲。系統總是會出現各種各樣的問題。下面來分析一下為什麼說CAP理論只能滿足兩條。

三、驗證CAP理論

既然系統總是會有錯誤,那我們就來看看可能會出現什麼錯誤。

分佈式系統中的CAP理論,面試必問,你理解了嘛?

N1節點更新了V0到V1,想在也想把這個消息通過M操作告訴N1節點,卻發生了網絡故障。這時候小明和小華都要同時訪問這個數據,怎麼辦呢?現在我們依然想要我們的系統具有CAP三個特性,我們分析一下會發生什麼。

(1)系統網絡發生了故障,但是系統依然可以訪問,因此具有容錯性。

(2)小明在訪問節點N1的時候更改了V0到V1,想要小華訪問節點N2的V數據庫的時候是V1,因此需要等網絡故障恢復,將N2節點的數據庫進行更新才可以。

(3)在網絡故障恢復的這段時間內,想要系統滿足可用性,是不可能的。因為可用性要求隨時隨地訪問系統都是正確有效的。這就出現了矛盾。

正是這個矛盾所以CAP三個特性肯定不能同時滿足。既然不能滿足,那我們就進行取捨。

有兩種選擇:

(1)犧牲數據一致性,也就是小明看到的衣服數量是10,買了一件應該是9了。但是小華看到的依然是10。

(2)犧牲可用性,也就是小明看到的衣服數量是10,買了一件應該是9了。但是小華想要獲取的最新的數據的話,那就一直等待阻塞,一直到網絡故障恢復。

現在你可以看到了CAP三個特性肯定是不能同時滿足的,但是可以滿足其中兩個。

三、CAP特性的取捨

我們分析一下既然可以滿足兩個,那麼捨棄哪一個比較好呢?

(1)滿足CA捨棄P,也就是滿足一致性和可用性,捨棄容錯性。但是這也就意味著你的系統不是分佈式的了,因為涉及分佈式的想法就是把功能分開,部署到不同的機器上。

(2)滿足CP捨棄A,也就是滿足一致性和容錯性,捨棄可用性。如果你的系統允許有段時間的訪問失效等問題,這個是可以滿足的。就好比多個人併發買票,後臺網絡出現故障,你買的時候系統就崩潰了。

(3)滿足AP捨棄C,也就是滿足可用性和容錯性,捨棄一致性。這也就是意味著你的系統在併發訪問的時候可能會出現數據不一致的情況。

實時證明,大多數都是犧牲了一致性。像12306還有淘寶網,就好比是你買火車票,本來你看到的是還有一張票,其實在這個時刻已經被買走了,你填好了信息準備買的時候發現系統提示你沒票了。這就是犧牲了一致性。

但是不是說犧牲一致性一定是最好的。就好比mysql中的事務機制,張三給李四轉了100塊錢,這時候必須保證張三的賬戶上少了100,李四的賬戶多了100。因此需要數據的一致性,而且什麼時候轉錢都可以,也需要可用性。但是可以轉錢失敗是可以允許的。


分享到:


相關文章: