拜託!這才是分布式系統CAP的正確打開方式

csdn 發佈 2020-08-25T16:05:28+00:00

作者 | bdseeker責編 | 鄭麗媛來源 | BigData之路(ID:bigdata3186)前言糾結了很久要不要寫這一篇,作為分布式系統的核心理論簡單說說容易,聊透卻很難,轉念一想,如果不寫這篇,算什麼想通透大數據呢!

作者 | bdseeker

責編 | 鄭麗媛

來源 | BigData之路(ID:bigdata3186)

前言

糾結了很久要不要寫這一篇,作為分布式系統的核心理論簡單說說容易,聊透卻很難,轉念一想,如果不寫這篇,算什麼想通透大數據呢!並且這本身就違背了我寫作的初衷;加之正好前幾天和同事以Zookeeper的用戶行為反推了CAP理論,回過頭來細琢磨了下,還蠻有意思的!閒話少絮,我們進入正題!

本文宗旨:深入淺出!聊透!

「紙面」上的CAP

相信很多同學都聽過CAP這個理論,為了避免我們認知不同,我們先來統一下知識起點。

  • CAP理論在1999年一經提出就成為了分布式系統領域的頂級教義。並表明分布式服務中,存在三要素:一致性、可用性、分區容錯性。而「CAP」就是Consistency/Availability/Partition Tolerance三個單詞縮寫。

  1. 一致性:分布式系統中,一份數據一般會存在多個副本,要求多副本數據對於數據的更新與單份數據相同,即強一致性。

  2. 可用性:在任意的時刻,對分布式系統來說要保證在限定延時內正常響應客戶端的讀寫請求,並且不會報錯。(提前糾正一個誤區,這裡的可用性並不是咱們通常理解的服務的SLA可用性,即3個9、4個9之類的定義。實際上指的是是數據訪問的可達性。)

  3. 分區容錯性:在分布式服務中,節點之間網絡通信異常導致(丟包、延遲、中斷等)的網絡分區現象是必然存在的,要保證出現網絡分區現象時,分布式系統不受影響。


原論述表明CAP是不可以兼得的,一個系統需要放寬一點才能滿足其他兩點,因此此時對於分布式系統來說其實就三個選項CP、AP、CA三種,但是不能同時滿足CAP。但是由於網絡問題是不可避免的現象,所以預想的分布式系統都會往AP和CP上去權衡靠攏。如下所示:

CAP模型

  • 嘗試沙盤推演分布式系統的CA、AP、CP選型

1. 先說說CA選型

實際上CA選型對於我們來說並不陌生,Oracle和MySQL資料庫就是最好的例子,他們擁有強一致性和可用性,雖然Oracle RAC看似是分布式,但是依然選擇節點本身的共享存儲或者邏輯ASM存儲;MySQL主從實際上可以理解成多個單點MySQL,通過Binlog數據同步逐漸將數據同步到所有單點上,寫主讀從,因此依舊是是單點的CA系統,捨棄了P。我們暫時不討論資料庫事務。這裡我們主要還是聊聊正兒八經的分布式系統。

2. 為什麼CP系統不能滿足A?

CP系統意味著是數據是單副本,分布在多個節點上,如下圖所示,D1-Dn代表著分布式系統的多個節點,當不同的Client訪問節點上的數據時,由於不涉及副本數據的同步,每個節點都是最新的數據,數據必然是強一致性的。此時是滿足C、P要素。但是此時如果發生網絡分區問題,那麼數據就必然丟失不可訪問了,此時可用性A受到了影響。

3. 為什麼AP系統不能滿足C?

AP系統意味著數據是有多副本的,即使出現網絡分區問題,也不會丟失數據導致不可用,但是會存在數據一致性問題。如下圖所示,數據D1有3個副本,D1-1、D1-2、D1-3,並且分布在不同節點上。在T1時刻,正常情況下每個客戶端讀到的數據都是X=1,在T2時刻,Client1嘗試將數據更新為X=2,接下來T3時刻請求到達分布式系統後端,將D1-1副本數據更新成功,但是在T4時刻數據副本D1-1和D1-2副本之間出現網絡分區問題,D1-2並未被置成X=2,此時Client2和Client3讀一份數據就出現了不同的返回值,雖然數據可達,但是由此帶來了數據一致性問題。

AP選型

如果看到這裡並且理解了,那麼恭喜你,證明你對分布式確實有一定的理解了。我們再接再厲,繼續往下看,相信你對CAP的理解會上一個層次。

在CAP中「迷失」

在上一節中我們解析了「紙面」上的CAP,按照其推論,分布式系統的世界看似很完美,絕大多數架構師也將CAP奉為第一原則,在設計系統之初就選擇傾向於CP或者AP。即為了保證強一致性犧牲可用性或者為了可用性而降低一致性。

可是仔細一想,上一節所講述的分布式世界真的這麼完美嗎?細細想來,誤區太多了!

  • 誤區一 "三選二"的先入為主

儘管網絡問題在我們日常運營分布式系統中經常發生,但是相比正常時間,網絡分區依然是小機率事件,因此並不應該在設計之處就放棄C或者A,在正常情況下分布式系統一定是要同時兼顧CAP。

  • 誤區二 CAP的定義極端

在上面的CAP理論中,分布式系統在網絡分區的既定現實下一定會保證P,而在A、C中選取其一,但事實上A、C的選擇並不是非黑即白的。因此上面的CAP理論過於粗曠籠統。

  1. 設計具體分布式服務時,實際上需要區分多個子模塊,如計算模塊/調度模塊/存儲模塊等,在遭遇網絡分區時,會實行將部分子模塊降級等策略,從而細粒度取捨A和C,而不是直接影響整個服務、所有數據。

  • 誤區三 CAP的標準模糊

CAP理論中只為C、A、P定義概念,但是卻不定義標準,C、A、P3個要素都是定義在時間這個維度的基礎上,一切都是基於時間視圖,多長時間的數據算不違反一致性呢?多久的訪問時間算影響數據訪問的可用性呢?或者再較真一點,多久時間的網絡問題算作網絡分區呢?一切的本質都是時間。因此在理論基礎上需要將CAP定性細分。

  1. 針對網絡分區可以按照一定通信周期,分斂成單機網絡分區、機器組網絡分區(比如HDFS的機架感知實際上就是針對的就是後者);

  2. 針對一致性可以分成若干種一致性程度(後面的文章會講到);

  3. 針對數據訪問效率來說,按照P95/P99讀寫進行數據訪問性能的進行區分也不失為一種手段。

  • 誤區四 CAP理論是否要帶Client玩?

CAP理論中並沒有明確係統邊界範圍,一個分布式系統不包括Client那算什麼分布式系統的呢?這裡我們就來嘮嘮CAP理論為什麼不包括Client。因為如果算上client的話,分布式集群將更為複雜。

  1. 假設網絡分區發生在Cient和分布式服務中間,那麼A肯定就無法達到了。

  2. 分布式服務一致性的效果就不是這麼明顯了,因為讀請求都到不了分布式系統。

  3. 如果Client和分布式服務中間發生網絡分區,此時分布式服務無論再怎麼努力其實都是無用的。


雖然不帶著Client玩,但並不意味著Client不需要重視,個人認為分布式系統的Client中一定要儘量保證CA,而不必去考慮P。

CAP的正確打開方式

上面提到了,由於傳統CAP理論的存在一些誤區點,其將很多同學帶入錯誤的方向上,這裡開始我們聊一聊CAP的正確打開方式。

CAP的目標狀

如上圖所示:在未發生網絡分區的T1時刻,這時的分布式系統是同時滿足CAP三要素的,各份數據一致性狀態是S,當到了T2時刻,發生了網絡分區情況,此時各個節點,會記錄各個節點的狀態S1、S2,當T3時刻網絡分區恢復時,需要將S1、S2狀態進行相應處理,這裡的部分實際上是很多分布式服務的重點:比如可以通過log end offset(Kafka)或者transaction id(Zookeeper)在分區發生後進行leader比對選舉,然後再進行數據同步。

  • 精細化CAP理論

CAP為我們打開了一扇大門,但是過於寬泛無法適合所有場景,比如不適合資料庫事務,而強一致性C也會使得服務應用場景受限,因此理論需要細分領域,根據不同場景進行分類。

1.ACID原則

  • 原子性(Atomicity)在事務中一個事務要麼成功,要麼失敗。不允許一個事務成功一半失敗一半。原子性就像我中午午休經常會去超市買水果,要麼就買選蘋果+結完帳才算購買成功;蘋果沒選好或者選好了沒結帳 都不算購買成功。

  • 一致性(Consistency)在事務的開始和結束時,需要滿足一致性約束條件。什麼是一致性約束,咱們依舊拿去超市買蘋果舉例,超市只剩下20個蘋果了,我買了一個,對應的超市就應該減去一個蘋果。另外注意ACID中的一致性,是邏輯的一致性,而不是CAP中數據的一致性。

  • 獨立性(Isolation)如果有多個事務同時發生,互相之間不能被影響,並且不知道對方的存在。咱們還去買蘋果,我挑了蘋果去結帳,有個大媽也挑了蘋果也去結帳。這時我們之間是互不影響的,相互獨立的。我沒帶錢買蘋果失敗也不影響大媽買蘋果成功。當然如果結完帳大媽看小伙子我長得帥,硬給我塞幾個蘋果,我也沒辦法😄

  • 持久性(Durability)當事務運行成功的時候,對整個系統來說,這個更新就是永久的。我們依舊去去買蘋果,買完蘋果結帳之後,如果蘋果是好的,我想退款,超市是不會給我退的,對於超市來說這個帳單永久的,除非我買到了壞蘋果並且退款成功。

以上就是資料庫系統里的ACID原則,主要針對資料庫事務,分布式事務我們後續的文章會講到。

2.BASE原則(這裡就不用買蘋果舉例了,因為找不到同一個蘋果的多個副本。😄 )

  • 基本可用(Basically Available)系統大多數時間是可用的,允許偶爾的失敗。相比CAP的可用性來說,BASE中的基本可用,是允許分布式服務在請求響應時間上有損失的,原來10ms返回,現在100ms也不算做異常。

  • 軟狀態(Soft State)允許分布式系統中的數據存在一個中間狀態,這就意味允許系統在多個不同節點的數據副本存在數據延時。比如Kafka 的partition多個replica之間並不是一直同步的。相比CAP強一致性這種硬狀態來說,BASE中的S是允許同一數據的多副本之間存在延時的軟狀態。

  • 最終一致性(Eventual Consistency)上面說到允許分布式系統存在中間的軟狀態,但是總得有個時間期限。否則就沒法玩兒了。在這個時間周期過後,必須保證所有副本保持數據一致性。從而達到數據的最終一致性。

3.CAP和BASE、ACID的關係

AP、BASE和ACID的關係

如上圖所示,BASE和ACID實際上是CAP在不同選型的細分理論,CA的選型對應ACID原則,主要針對資料庫系統Oracle、MySQL等,AP選型對應BASE原則,比如Cassandra、Zookeeper、HDFS,而CP選型很遺憾目前還沒有一個原則能對應上。但是不妨礙咱們造一個,比如「BACP」,即基本可用、強一致性、分區容錯性,其對應的系統如HBase、Redis。

雖然CAP想在任意時刻都滿足比較難,但是還是不妨礙有巔峰產品問世,比如谷歌的Spanner雖然是CP系統,但是由於可用性非常之高,讓用戶一直以為他是CAP的產品,其依賴谷歌自建廣域網,讓我了解到基建的發達也是解決分布式系統網絡分區問題的另一個方向;Tidb作為國內的開源代表,也是CP系統,雖然他距離Spanner還有差距,但是他公司的名字PingCAP讓我覺得,趕超只是時間問題。此外還有OceanBase也非常不錯,這塊了解的較少,以後有機會了解下。

至此CAP就解析完了,如果你能看到這裡,我必須手動點讚!祝咱們在大數據的路上越走越遠!相信堅持總會有所收穫!!!

關鍵字: