CAP理論

bytecc發表於2021-05-06

一致性(Consistency) 可用性(Availability) 分割槽容錯性(Partition Tolerance)

一致性

一致性說的是客戶端的每次讀操作,不管訪問哪個節點,要麼讀到的都是同一份最新的數 據,要麼讀取失敗。你可以看到,一致性強調 的不是資料完整,而是各節點間的資料一致。比如kv系統又兩個節點,初始x=1,當客戶端傳送set x=2到節點1,節點1修改資料x=2同時通知節點2修改x=2,都修改成功後節點1才返回修改成功給客戶端。

問題:如果節點2出現故障,那麼節點1一直不能返回修改成功給客戶端,造成系統不可用。

可用性

可用性說的是任何來自客戶端的請求,不管訪問哪個節點,都能得到響應資料,但不保證是 同一份最新資料。你也可以把可用性看作是分散式系統對訪問本系統的客戶端的另外一種承 諾:我盡力給你返回資料,不會不響應你,但是我不保證每個節點給你的資料都是最新的。 這個指標強調的是服務可用,但不保證資料的一致。

問題:客戶端訪問不同節點,資料可能不一致

分割槽容錯性

當節點間出現任意數量的訊息丟失或高延遲的時候,系統仍然可以繼續提供服務。也就是說,分散式系統在告訴訪問本系統的客戶端:不管我的內部出現什麼樣的資料同步問題,我會一直執行,提供服務。這個指標,強調的是叢集對分割槽故障的容 錯能力。作為分散式系統來說,內部節點出現故障是一定的,所有這個特性是一定要考慮的。

CAP只能三個選兩個,而P是一定要考慮的,所有設計系統一般是一致性和可用性二選一。

追求一致性CP

就是實現分散式系統的 ACID 特性,需要用到分散式事務協議,比如二階段提交協議 和 TCC(Try-Confirm-Cancel)

二階段提交協議(第一次先問其他節點能不能做,全部回答能做才第二次提交,有一個不能就返回失敗給客戶端)

比如三個節點,客戶端連線節點1傳送一個操作,節點1就是協調者(Coordinator),協調者透過兩次提交統一結果,返回給客戶端(全部執行或者全部不執行)

在第一個階段,每個參與者投票表決事務是放棄還是提交。一旦參與者投票 要求提交事務,那麼就不允許放棄事務。也就是說,在一個參與者投票要求提交事務之前, 它必須保證能夠執行提交協議中它自己那一部分,即使參與者出現故障或者中途被替換掉。 這個特性,是我們需要在程式碼實現時保障的。

缺點:第一次提交的時候,所有節點就要把需要操作的資料鎖住,保證最終能夠執行成功。這會影響系統的併發效能。

TCC(Try-Confirm-Cancel)

TCC 是 Try(預留)、Confirm(確認)、Cancel(撤銷) 3 個操作的簡稱,它包含了預 留、確認或撤銷這 2 個階段。客戶端同時通知三個節點預留資源,當客戶端都收到預留成功時,再同時通知三個節點確認操作。這個其實是由程式碼來實現的。

追求可用性AP

AP模型沒有固定的模型,但是根據實際經驗來說,AP分散式系統的核心理論就是基本可用(Basically Available)和最終一致性(Eventually consistent)

基本可用實現

流量削峰、延遲響應、體驗降級、過載保護這 4 板斧,更能理解這 4 板斧背後的妥協折中,從而靈活地處理不可預知的突發問題。

最終一致性

系統中所有的資料副本在經過一段時間的同步後,最終能夠達到一個一致的狀態。也就是說,在資料一致性上,存在一個短暫的延遲。

如果業務的某功能無法容忍一致性的延遲 (比如分散式鎖對應的資料),需要實現的是強一致性;如果能容忍短暫的一致性的延遲 (比如 QQ 狀態資料),就可以考慮最終一致性。

實現最終一致性的具體方式是什麼?

讀時修復:在讀取資料時,檢測資料的不一致,進行修復

寫時修復:在寫入資料,檢測資料的不一致時,進行修復。具體來說,Cassandra 叢集的節點之間遠端寫資料的時候,如果寫失敗就將資料快取下來,然後定時重傳,修復資料的不一致性(效能消耗小)。

非同步修復:這個是最常用的方式,透過定時對賬檢測副本資料的一致性,並修復。

Gossip 協議

這個協議可以達到最終一致性

Gossip 的三板斧分別是:直接郵寄(Direct Mail)、反熵(Anti-entropy)和謠言傳播 (Rumor mongering)。

直接郵寄:就是直接傳送更新資料,當資料傳送失敗時,將資料快取下來,然後重傳。比如節點1向節點2,3傳送資料,但是返回失敗,節點1會把資料寫入佇列快取,不斷的去通知節點2,3.直到通知成功。

缺點:快取佇列滿了後,寫不進去,就會導致最終不一致。

反熵指的是叢集中的節點,每隔段時間就選擇某個其他節點,然後透過互相交換自己的 所有資料來消除兩者之間的差異,實現資料的最終一致性。常用的是節點組成一個閉環,比如節點a->b->c->a->b.這樣所有節點的資料就保持一致了。這個要求所有節點都已知。

謠言傳播,廣泛地散播謠言,它指的是當一個節點有了新資料後,這個節點變成活躍狀態, 並週期性地聯絡其他節點向其傳送新資料,直到所有的節點都儲存了該新資料。當節點數不確定時,可以使用。

Quorum NWR演算法

要靈活地自定義一致性,可以自定義一致性的級別。

比如我們實現了一個AP系統,可以達成最終一致性,但是突然有個需求,我們要拉這幾個業務的資料做實時分析,希望資料寫入成功後,就能立即讀取到新資料,也就是要實現強一致性。

強一致性能保證寫操作完成後,任何後續訪問都能讀到更新後的值;

最終一致性只能保證如果對某個物件沒有新的寫操作了,最終所有後續訪問都能讀到相 同的最近更新的值。也就是說,寫操作完成後,後續訪問可能會讀到舊資料。

在原有系統上開發實現一個新功能,就可以滿足業務同學的需求了。因為透過 Quorum NWR,你可以自定義一致性級別,透過臨時調整寫入或者查詢的方式,當 W + R > N 時,就可以實現強一致性了。常用的AP系統中,Quorum NWR是通常都會實現的一個功能,可以滿足某些強一致性的場景。

Quorum NWR 的三要素

N 表示副本數,又叫做複製因子(Replication Factor)。也就是說,N 表示叢集中同一份資料有多少個副本。在實現 Quorum NWR 的時候,你需要實現自定義副本的功能。也就是 說,使用者可以自定義指定資料的副本數

W,又稱寫一致性級別(Write Consistency Level),表示成功完成 W 個副本更新,才完成寫操作,比如設定write level = 2,表示這個寫操作要完成了 2 副本的更新才算寫成功。

R,又稱讀一致性級別(Read Consistency Level),表示讀取一個資料物件時需要讀 R 個副本。你可以這麼理解,讀取指定資料時,要讀 R 副本,然後返回 R 個副本中最新的那份資料。Read level =2.

本作品採用《CC 協議》,轉載必須註明作者和本文連結
用過哪些工具?為啥用這個工具(速度快,支援高併發...)?底層如何實現的?

相關文章