保證一致性嗎 分布式系統 一致性協議

2021-10-16 07:49:37 字數 3996 閱讀 1664

一致性模型本質上是程序與資料儲存的約定,通過一致性模型我們可以理解和推理在分布式系統中資料複製需要考慮的問題和基本假設。那麼,一致性模型的具體實現有一些呢?本文會介紹一致性協議實現的主要思想和方法。

一致性協議描述了特定一致性模型的實際實現。一致性模型就像是介面,而一致性協議就像是介面的具體實現。一致性模型提供了分布式系統中資料複製時保持一致性的約束,為了實現一致性模型的約束,需要通過一致性協議來保證。

一致性協議根據是否允許資料分歧可以分為兩種:

可以發現,它們的核心區別在於是否允許多個節點發起寫操作,單主協議只允許由主節點發起寫操作,因此它可以保證操作有序性,一致性更強。而多主協議允許多個節點發起寫操作,因此它不能保證操作的有序性,只能做到弱一致性。

值得注意的是,一致性協議的分類方式有很多種,主要是看從哪個角度出發進行歸類,常用的另乙個歸類方式是根據同步/非同步複製來劃分,這裡就不多做討論了。下面對單主協議和多主協議分別做一些共性的分析,篇幅所限,不會深入到協議細節。

單主協議的共同點在於都會用乙個主節點來負責寫操作,這樣能夠保證全域性寫的順序一致性,它有另乙個名字叫定序器,非常的形象。

主備複製可以說是最常用的資料複製方法,也是最基礎的方法,很多其他協議都是基於它的變種。主備複製要求所有的寫操作都在主節點上進行,然後將操作的日誌傳送給其他副本。可以發現由於主備複製是有延遲的,所以它實現的是最終一致性。

主備複製的實現方式:主節點處理完寫操作之後立即返回結果給客戶端,寫操作的日誌非同步同步給其他副本。這樣的好處是效能高,客戶端不需要等待資料同步,缺點是如果主節點同步資料給副本之前資料缺失了,那麼這些資料就永久丟失了。mysql 的主備同步就是典型的非同步複製。

兩階段提交(2pc)是關係型資料庫常用的保持分布式事務一致性的協議,它也屬於同步複製協議,即資料都同步完成之後才返回客戶端結果。可以發現 2pc 保證所有節點資料一致之後才返回給客戶端,實現了順序一致性。

2pc 把資料複製分為兩步:

表決階段:主節點將資料傳送給所有副本,每個副本都要響應提交或者回滾,如果副本投票提交,那麼它會將資料放到暫存區域,等待最終提交。

提交階段:主節點收到其他副本的響應,如果副本都認為可以提交,那麼就傳送確認提交給所有副本讓它們提交更新,資料就會從暫存區域移到永久區域。只要有乙個副本返回回滾就整體回滾。

可以發現 2pc 是典型的 ca 系統,為了保證一致性和可用性,2pc 一旦出現網路分割槽或者節點不可用就會被拒絕寫操作,把系統變成唯讀的。由於 2pc 容易出現節點宕機導致一直阻塞的情況,所以在資料複製的場景中不常用,一般多用於分布式事務中(注:實際應用過程中會有很多優化)。

分割槽容忍的一致性協議跟所有的單主協議一樣,它也是只有乙個主節點負責寫入(提供順序一致性),但它跟 2pc 的區別在於它只需要保證大多數節點(一般是超過半數)達成一致就可以返回客戶端結果,這樣可以提高了效能,同時也能容忍網路分割槽(少數節點分割槽不會導致整個系統無法執行)。分割槽容忍的一致性演算法保證大多數節點資料一致後才返回客戶端,同樣實現了順序一致性。

下面用乙個簡單的示例來說明這類演算法的核心思想。假設現在有乙個分布式檔案系統,它的檔案都被複製到 3 個伺服器上,我們規定:要更新乙個檔案,客戶端必須先訪問至少 2 個伺服器(大多數),得到它們同意之後才能執行更新,同時每個檔案都會有版本號標識;要讀取檔案的時候,客戶端也必須要訪問至少 2 個伺服器獲取該檔案的版本號,如果所有的版本號一致,那麼該版本必定是最新的版本,因為如果前面的更新操作要求必須要有大多數伺服器的同意才能更新檔案。

以上就是我們熟知的 paxos、zab、raft 等分割槽容忍的一致性協議的核心思想:一致性的保證不一定非要所有節點都保持一致,只要大多數節點更新了,對於整個分布式系統來說資料也是一致性的。上面只是乙個簡單的闡述,真正的演算法實現是比較複雜的,這裡就不展開了。

分割槽容忍的一致性協議如 paxos 是典型的 cp 系統,為了保證一致性和分割槽容忍,在網路分割槽的情況下,允許大多數節點的寫入,通過大多數節點的一致性實現整個系統的一致性,同時讓少數節點停止服務(不能讀寫),放棄整體系統的可用性,也就是說客戶端訪問到少數節點時會失敗。

值得注意的是,根據 cap 理論,假設現在有三個節點 a、b、c,當 c 被網路分割槽時,有查詢請求過來,此時 c 因為不能和其他節點通訊,所以 c 無法對查詢做出響應,也就不具備可用性。但在工程實現上,這個問題是可以被繞過的,當客戶端訪問 c 無法得到響應時,它可以去訪問 a、b,實際上對於整個系統來說還是部分可用性的,並不是說 cp 的系統一定就失去可用性。詳細的分析參考分布式系統:cap 理論的前世今生

相比單主協議為了實現順序一致性,不允許多個節點併發寫,多主協議恰恰相反,只保證最終一致性,允許多個節點併發寫,能夠顯著提公升系統效能。由於多主協議一般提供的都是最終一致性,所以常用在對資料一致性要求不高的場景中。

gossip 協議就是一種典型的多主協議,很多分布式系統都使用它來做資料複製,例如位元幣,作為一條去中心化的公鏈,所有節點的資料同步都用的是 gossip 協議。此外,gossip 協議也在一些分布式資料庫中如 dynamo 中被用來做分布式故障檢測的狀態同步,當有節點故障離開集群時,其他節點可以快速檢測到。

從名稱上就可以看出 gossip 協議的核心思想,gossip 是流言八卦的意思,想想我們日常生活人與人之間傳八卦的場景,在學校裡面乙個八卦一旦有乙個人知道了,通過人傳人,基本上整個學校的人最終都會知道了。因此 gossip 協議的核心思想就是:每個節點都可以對其他節點傳送訊息,接收到訊息的節點隨機選擇其他節點傳送訊息,接收到訊息的節點也做同樣的事情。

多主協議允許執行多個節點併發寫,就一定會出現對乙個資料併發寫導致資料衝突的情況,因此這類協議都需要解決併發寫的問題。單主協議通過主節點控制寫入,保證不會出現併發寫的情況,因為所有寫操作最終都會通過主節點排序,從某種意義上講,使用單主協議的系統對於寫入實際上是序列的,因此其效能是有瓶頸的。而多主協議允許多節點併發寫,提搞了寫入的效能,但是實際上它是把資料合併的操作延遲了,單主協議在寫入的時候就進行了資料合併,因此讀取資料的時候如果出現資料衝突的時候,就需要對資料進行合併,保證全域性一致性。

前面我們提到位元幣使用的是 gossip 協議做資料複製,那麼問題來了,不是說多主協議效能會比較高嗎,為什麼位元幣的效能那麼差?這裡實際上要分開來看,由於位元幣是去中心化的,但是它的支付功能需要保證全域性資料一致性,因此它用了一種很巧妙的一致性演算法 pow:所有節點都做一道數學題,誰先算出答案誰有權利將交易寫到鏈上,然後利用 gossip 協議傳播它的答案和交易,其他節點驗證它的答案正確就將資料儲存起來。

到這裡你可能會有乙個疑問:pow 作為多主協議為什麼效能這麼低?任何協議都有它適用的場景。在位元幣這個場景中,它對於資料一致性是有強需求的,理論上用單主協議是最優的選擇。但是位元幣作為去中心化的數字貨幣是不會使用單主協議的,否則又變成中心化的系統了。因此位元幣只能選擇多主協議,通過 pow 協議將位元幣整條鏈操作進行了近似序列化,這樣才能降低出現雙花的概率(併發寫的時候乙個位元幣被消費多次),魚與熊掌不可兼得,既然要強一致性,那麼只能犧牲效能來換取。

由於多主協議允許了資料分歧,那麼就需要有解決資料衝突的策略來保證最終一致性。如果要嚴格區分的話,位元幣實際上應用了兩個一致性協議:

本文主要從是否允許資料分歧的角度將分布式一致性協議分為兩種:單主協議和多主協議。其中單主協議會用乙個主節點來負責寫操作,這樣能夠保證全域性寫的順序一致性,但因此也犧牲了一部分效能。而多主協議則允許寫操作可以由不同節點發起,並且同步給其他副本,只能保證最終一致性,但因此也提公升了系統併發寫入的效能。對資料一致性要求高的場景例如分布式資料庫,主要會使用單主協議,對資料一致性要求不高例如故障檢測,主要會使用多主協議來提高效能,當然也有特例,像位元幣為了去中心化使用 pow 和 gossip 結合進行資料複製。

值得注意的是,文中提到的單主、多主協議只是我個人對分布式一致性協議的一種分類方式,幫助我們更好的理解。讀者可以看一下參考資料,看一下不同作者對分布式協議是如何分類的,這樣對分布式一致性協議會有更深入的理解。

保證一致性嗎 Kafka的一致性保證

魚和熊掌不可兼得。系統設計需要根據具體的應用場景做出權衡。系統設計者可以通過配置kafka,來得到不同程度的需求滿足。每個kafka主題 topic 都分為多個分割槽 partitions 每個分割槽可以具有多個副本 replica 其中乙個副本是主分割槽 leader 所有讀寫請求都由主分割槽提供...

分布式一致性

分布式一致性是指在分布式環境中對某個副本資料進行更新操作時,必須確保其他副本也會更新,避免不同副本資料不一致。分布式系統乙個重要的問題時解決資料複製,一是為了增加系統的可用性防止單點故障,二是提高系統可用性,通過負載聚恆,使分布在不同位置的資料副本能夠提供服務。理想狀態下,當然希望分布式系統能夠實現...

分布式一致性

分布式系統的乙個重要問題是資料的複製。對資料的複製一般有兩個原因 資料複製的主要難題是保持各個副本的一致性。即在更新乙個副本時,必須確保同時更新其他的副本,否則資料的各個副本將不再相同。一致性模型實質上是程序和資料儲存之間的乙個約定。正常情況下,乙個資料項上執行讀操作時,它期待該操作返回的是該資料在...