分佈式系統:CAP 理論的前世此生

CAP 理論是分佈式系統設計中的一個重要理論,雖然它爲系統設計提供了很是有用的依據,可是也帶來了不少誤解。本文將從 CAP 誕生的背景提及,而後對理論進行解釋,最後對 CAP 在當前背景下的一些新理解進行分析,澄清一些對 CAP 的誤解。算法

CAP 理論誕生的背景

CAP 理論的是在「數據一致性 VS 可用性」的爭論中產生。CAP 的做者 Brewer 在 90 年代的時候就開始研究基於集羣的跨區域系統(實質上是早期的雲計算),對於這類系統而言,系統可用性是首要目標,所以他們採用了緩存或者過後更新的方式來優化系統的可用性。儘管這些方法提高了系統的可用性,可是犧牲了系統數據一致性。數據庫

Brewer 在 90 年代提出了 BASE 理論(基本可用、軟狀態、最終一致性),這在當時還不怎麼被接受。由於你們仍是比較看重 ACID 的優勢,不肯意放棄強一致性。所以,Brewer 提出了 CAP 理論,目的就是爲了開闊分佈式系統的設計空間,經過「三選二」的公式,解放思想,不要只抓着一致性不放。瀏覽器

理解了 CAP 誕生的背景,咱們才能更加深刻的理解 CAP 理論,以及它帶來的啓示。「三選二」的觀點雖然幫助你們開拓了設計思路,可是也帶來了不少誤解。下面咱們會逐一分析,首先來看一下 CAP 理論的解釋。緩存

CAP 理論的經典解釋

CAP 定理是分佈式系統設計中最基礎,也是最爲關鍵的理論。它指出,分佈式數據存儲不可能同時知足如下三個條件。網絡

  • 一致性(Consistency):每次讀取要麼得到最近寫入的數據,要麼得到一個錯誤。
  • 可用性(Availability):每次請求都能得到一個(非錯誤)響應,但不保證返回的是最新寫入的數據。
  • 分區容忍(Partition tolerance):儘管任意數量的消息被節點間的網絡丟失(或延遲),系統仍繼續運行。

CAP 定理代表,在存在網絡分區的狀況下,一致性和可用性必須二選一。當網絡發生分區(不一樣節點之間的網絡發生故障或者延遲較大)時,要麼失去一致性(容許不一樣分區的數據寫入),要麼失去可用性(識別到網絡分區時中止服務)。而在沒有發生網絡故障時,即分佈式系統正常運行時,一致性和可用性是能夠同時被知足的。這裏須要注意的是,CAP 定理中的一致性與 ACID 數據庫事務中的一致性大相徑庭。ACID 的 C 指的是事務不能破壞任何數據庫規則,如鍵的惟一性。與之相比,CAP 的 C 僅指單一副本這個意義上的一致性,所以只是 ACID 一致性約束的一個嚴格的子集。分佈式

CAP 理論看起來難理解,其實只要抓住一個核心點就能推導出來,不用死記硬背。在出現網絡分區的時候,優化

  • 若是系統不容許寫入,那麼意味着下降了系統的可用性,但不一樣分區的數據可以保持一致,即選擇了一致性。
  • 若是系統容許寫入,那麼意味着不一樣分區之間的數據產生不一致,系統可用性獲得保障,即選擇可用性。

CAP 的新理解

CAP 常常被誤解,很大程度上是由於在討論 CAP 的時候可用性和一致性的做用範圍每每都是含糊不清的。若是不先定義好可用性、一致性、分區容忍在具體場景下的概念,CAP 實際上反而會束縛系統設計的思路。首先,因爲分區不多發生,那麼在系統不存在分區的狀況下沒什麼理由犧牲 C 或 A。其次,C 與 A 之間的取捨能夠在同一系統內以很是細小的粒度反覆發生,而每一次的決策可能由於具體的操做,乃至由於牽涉到特定的數據或用戶而有所不一樣。最後,這三種性質均可以在程度上均可以進行度量,並非非黑即白的有或無。可用性顯然是在 0% 到 100% 之間連續變化的,一致性分不少級別,連分區也能夠細分爲不一樣含義,如系統內的不一樣部分對因而否存在分區能夠有不同的認知。雲計算

什麼是分區容忍

在現實世界中,正常狀況下分佈式系統各個節點之間的通訊是可靠的,不會出現消息丟失或者延遲很高的狀況,可是網絡是不可靠的,總會偶爾出現消息丟失或者消息延遲很高的狀況,這個時候不一樣區域的節點之間在一段時間內就會出現沒法通訊的狀況,也就是發生了分區。spa

分區容忍就是指分佈式系統在出現網絡分區的時候,仍然能繼續運行,對外提供服務。注意,這裏所說的仍然可以對外提供服務跟可用性的要求不同,可用性要求的是對於任意請求都能獲得響應,意味着即便出現網絡分區全部節點都可以提供服務。而分區容忍的重點在於出現網絡分區以後,系統仍然是可用的(包括部分可用)。設計

舉個例子:使用 Paxos 進行數據複製的系統就是典型的 CP 系統,即便出現網絡分區,主分區也可以提供服務,因此它是分區容忍的。再舉個反例:使用 2PC 進行數據複製的系統沒有分區容忍的特性,當出現網絡分區時,整個系統都會阻塞。

可用性的範圍

可用性其實很直觀:每次請求都能得到一個(非錯誤)響應,但不保證返回的是最新寫入的數據。換一個說法就是對於分佈式系統中的每一個節點,都可以對外部請求作出響應,但不要求一致性。

常常讓咱們疑惑的問題是衡量系統可用性的標準是什麼?其實關鍵點在於可用性的範圍,脫離了具體場景下的可用性範圍是沒有意義的。討論可用性是要有具體場景來劃分邊界的,簡單的認爲某個算法是知足可用性要求其實並不嚴謹,由於在工程實現中會有不少的技巧去彌補修正。

舉個例子:谷歌文檔就是很是典型的 AP 系統,它在網絡斷了的狀況下也可以使用。訣竅在於它在發現網絡斷了以後會進入離線模式,容許用戶繼續進行編輯,而後在網絡恢復以後再對修改的內容進行合併處理。能夠發現對於谷歌文檔來講,用戶的瀏覽器也是它系統的一個節點,當出現網絡分區時,它仍然可以爲用戶提供服務,可是代價是放棄了一致性,由於用戶作的修改只有本地知道,服務端是不清楚的。因此在這個例子裏面,可用性的範圍是包括了用戶瀏覽器在內的,不是咱們常規理解的分佈式系統的節點必定就是服務端的機器。

值得注意的是在現實世界中,咱們通常不會去追求完美的可用性,因此通常的說法是高可用,即儘量保證更多的節點服務可用。這也是爲何 Paxos 這類的一致性算法愈來愈流行的緣由之一。

一致性的範圍

討論一致性的時候必需要明確一致性的範圍,即在必定的邊界內狀態是一致的,超出邊界以外的一致性是無從談起的。好比 Paxos 在發生網絡分區的時候,在一個主分區內能夠保證完備的一致性和可用性,而在分區外服務是不可用的。值得注意的是,當系統在分區的時候選擇了一致性,也就是 CP,並不意味着徹底失去了可用性,這取決於一致性算法的實現。好比標準的兩階段提交發生分區的時候是徹底不可用的,而 Paxos 則保證了主分區的一致性和可用性。

通過上面的討論能夠發現,可用性的範圍要求比一致性的範圍要求要更嚴格,CAP 理論中的可用性要求的是整個系統的可用性,即便出現部分節點不可用也算是違反了可用性約束。而一致性的要求則沒有那麼高,發生網絡分區的時候只要保證主分區數據一致性,也認爲系統是符合一致性約束的。爲何這麼說呢?由於當出現網絡分區的時候,客戶端只要經過訪問主分區就能獲得最新的值(訪問超過半數以上節點,若是值都相同說明訪問的數據是最新的),此時系統是知足 CAP 理論中一致性的要求的。

管理分區

網絡分區是分佈式系統中必然發生的事情,經典的 CAP 理論是忽略網絡延遲的,可是在現實世界中,網絡延遲跟分區密切相關。也就是說當系統在有限的時間內沒法通訊達成一致(網絡延遲很高),就意味着發生了分區。此時就須要在一致性和可用性之間作出選擇:選擇繼續重試就意味着選擇一致性,放棄可用性;放棄數據一致性讓操做完成就意味着選擇了可用性。值得注意的是在分區的時候放棄數據一致性並非意味着徹底無論,通常工程實現會採用重試的方式達到最終一致性。

經過上面的分析能夠發現,平衡分區期間可用性和一致性的影響是分佈式系統設計中的關鍵問題。所以,管理分區不只是須要主動發現分區,還須要針對分區期間產生的影響準備恢復過程。也就是說咱們能夠從另外一個角度來應用 CAP 理論:系統進入分區模式的時候,如何在一致性和可用性之間作出選擇。

管理分區有三個步驟:

  • 檢測到分區開始
  • 明確進入分區模式,限制某些操做
  • 當通訊恢復後啓動分區恢復過程

當系統進入分區模式以後,有兩種選擇:

  • 選擇一致性:例如 Paxos 算法,只有大多數的主分區可以進行操做,其餘分區不可用,當網絡恢復以後少數節點跟多數節點同步數據。
  • 選擇可用性:例如谷歌文檔,出現分區時進入離線模式,等網絡恢復了客戶端跟服務端數據進行合併恢復。

總結

理論抽象於現實,服務於現實,但毫不等於現實。對 CAP 理論「三選二」的誤解就源於咱們常常把理論等同於現實。CAP 的誕生主要是爲了拓寬設計思路,不要侷限在強一致性的約束中。簡單的把「三選二」進行套用反而限制了設計思路。在現實世界中,不一樣業務場景對可用性和一致性的要求不同,而且一致性和可用性的範圍和區間是動態變化的,並非非此即彼。所以,準確理解 CAP 理論,從管理分區的角度出發,結合具體的業務場景,才能作出更好的系統設計。


原文連接 本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索