分佈式系統一致性

1 理論

1.1 ACID事務特性

  • A(原子性)事務的原子操做單元,對數據的修改,要麼所有執行,要麼所有不執行
  • C(一致性)在事務開始和完成時,數據必須保持一致狀態,相關的數據規則必須應用於事務的修改,以保證數據的完整性,事務結束時,全部的內部數據結構必須正確,僅僅是正確就能夠了,並無要求系統內的數據在整體上處於不變的狀態
  • I(隔離性)保證事務不受外部併發操做的獨立環境執行
  • D(持久性)事務完成以後,對於數據的修改是永久的,即便系統出現故障也可以保持

1.2 一致性等級

強一致性:這種一致性級別是最符合用戶直覺的,它要求系統寫入什麼,讀出來的也會是什麼,用戶體驗好,但實現起來每每對系統的性能影響大react

弱一致性:這種一致性級別約束了系統在寫入成功後,不承諾當即能夠讀到寫入的值,也不久承諾多久以後數據可以達到一致,但會盡量地保證到某個時間級別(好比秒級別)後,數據可以達到一致狀態算法

最終一致性:最終一致性是弱一致性的一個特例,系統會保證在必定時間內,可以達到一個數據一致的狀態。這裏之因此將最終一致性單獨提出來,是由於它是弱一致性中很是推崇的一種一致性模型,也是業界在大型分佈式系統的數據一致性上比較推崇的模型數據庫

最終一致性在弱一致性的基礎上加上了時間規定,也就是說在某個時間點之後會實現數據的最終一致性。網絡

1.3 CAP分佈式理論

  • C(一致性)一致性是指數據的原子性,在經典的數據庫中經過事務來保障,事務完成時,不管成功或回滾,數據都會處於一致的狀態,在分佈式環境下,一致性是指多個節點數據是否一致;
  • A(可用性)服務一直保持可用的狀態,當用戶發出一個請求,服務能在必定的時間內返回結果;
  • P(分區容忍性)在分佈式應用中,可能由於一些分佈式的緣由致使系統沒法運轉,好的分區容忍性,使應用雖然是一個分佈式系統,可是好像一個能夠正常運轉的總體

根據CAP理論,一個系統只能知足其中兩個。而分佈式爲了高可用,和分區容災(高可擴),捨棄了一致性。數據結構


分佈式系統中:併發

一致性:主要是指數據在多個副本之間可否保持一致的特性。在一致性的需求下,當一個系統在數據一致的狀態下執行更新操做後,應該保證系統的數據仍然處於一直的狀態。分佈式

可用性:指系統提供的服務必須一直處於可用的狀態,對於用戶的每個操做請求老是可以在有限的時間內返回結果。這裏的重點是"有限時間內"和"返回結果"。性能

分區容錯性:分佈式系統在遇到任何網絡分區故障的時候,仍然須要可以保證對外提供知足一致性和可用性的服務,除非是整個網絡環境都發生了故障。動畫

 

1.4 BASE理論

BASE是Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性)三個短語的縮寫。日誌

BASE理論是對CAP中一致性和可用性權衡的結果,其來源於對大規模互聯網系統分佈式實踐的總結, 是基於CAP定理逐步演化而來的。BASE理論的核心思想是:即便沒法作到強一致性,但每一個應用均可以根據自身業務特色,採用適當的方式來使系統達到最終一致性。

BASE中的三要素:

基本可用:指分佈式系統在出現不可預知故障的時候,容許損失部分可用性。系統此時仍然可用,只是服務可能被延遲。

軟狀態:指容許系統中的數據存在中間狀態,並認爲該中間狀態的存在不會影響系統的總體可用性,即容許系統在不一樣節點的數據副本之間進行數據同步的過程存在延時

最終一致性:強調的是全部的數據副本,在通過一段時間的同步以後,最終都可以達到一個一致的狀態。所以,最終一致性的本質是須要系統保證最終數據可以達到一致,而不須要實時保證系統數據的強一致性。

BASE理論面向的是大型高可用可擴展的分佈式系統,和傳統的事物ACID特性是相反的

 

2 paxos協議

2.1 base paxos

流程是這樣的:

每臺主機都是提議者也是接受者,(不然若是全部的主機都要修改,那麼將會沒有接受者)

預提案階段:

  1. 每臺須要提案的主機,生成一個全局位移的id,做爲提案id,能夠利用時間戳+本機ip地址的方式。而後將該提案發送給其餘全部主機
  2. 其餘主機收到提案id,之後若是目前保存的id爲空,或是小於該id,那麼就會將本身保存的提案id改成接收到的提案id,並向該主機回覆:等待你的正式提案,表示支持。若是本身已經批准了一個提案,也就是說接受了一個值,那麼就回復該值和該值的提案id

批准階段

  1. 一個提案者得到了一半以上(包括本身)的支持之後,若是收到了接受者表示本身已經批准了一個值,那麼從這些接受者中選擇一個提案id最大的,選擇它的提案值,做爲正式提案,帶上本身的提案id向本身的支持者廣播。若是不夠一半以上,那麼退出。如
  2. 當接受者收到了正式提案,若是提案id大於等於本身保存的,那麼就接受該批准。並回復提案者。若是提案id小於本身保存的,那麼就回復提案者,讓其中斷提案。

當一個提案者收到了一半以上的批准之後,造成一個多數派,向外廣播表示某個值已經被肯定。

 

情形:

批准階段,若是沒有接收到足夠支持,那麼退出本輪。不在參與。批准階段,在提交正式提案的時候,若是已經有接受者接受了別的值,那麼提交者中斷本次提案,同時向已經批准了本身的提案的接受者,表示個人提案已經終止了,請放棄批准。而後從新生成一個提案ID從新選舉。

2.2 multi paxos

Multi Paxos先運行一次完整的paxos算法選舉出leader,惟一的leader,在leader有效期內全部的議案都只能由leader發起。

Multi-Paxos協議並不假設全局必須只能有惟一的leader來生成日誌,它容許有多個「自認爲是leader的server」來併發生成日誌,這樣的場景即退化爲Basic-Paxos。經過lease機制,保持這個leader的身份,使得其餘proposer再也不發起提案,這樣就進入了一個leader任期。在leader任期中,因爲沒有了併發衝突,這個leader在對後續的日誌進行投票時,沒必要每次都向多數派詢問logID,也沒必要執行prepare階段,直接執行accept階段便可。

2.3 fast paxos

fast paxos 則直接假設本身就是一個leader,他的提案id=0,若是批准的大於一半以上,則向外廣播肯定了某個值,若是小於一半以上,表示發生衝突,回退到base paxos

 

3 raft協議

動畫介紹

 全部主機存在三種狀態,leader,follow,和candidate.

follow 徹底被動的接受leader的消息,當超時一段時間沒接受到消息就認爲leader沒了,那麼本身會成爲candidate,準備本身競選leader

 

剛開機是全部的主機都是leader,隨着時間推移,沒有接到leader的消息,部分主機開始退化爲leader,而後向其餘的全部節點開始拉票,當超過一半的節點贊成之後,那麼稱爲leader。贊成的節點稱爲該節點的follow。進行心跳檢測。

當須要同步日誌的時候,leader向全部的follow廣播,當收到一半以上的節點確認該條日誌的時候,leader在發送一條commit消息,表示該條日誌複製成功。

 

當網絡故障,分割了主機的時候,仍然須要一半以上的主機確認才能寫入日誌。

 

能夠設置不一樣節點的超時時間不一樣,能夠避免同一時間多個節點同時競爭leader。可是並不能徹底的避免,所以每臺機器,在收到不超過通常贊成之後,會延時一段時間進行選舉,這個延時時間各個機器再次不一樣。

 

4 分佈式事務

參考文章

分佈式事務是指會涉及到操做多個數據庫的事務。其實就是將對同一庫事務的概念擴大到了對多個庫的事務。目的是爲了保證分佈式系統中的數據一致性。分佈式事務處理的關鍵是必須有一種方法能夠知道事務在任何地方所作的全部動做,提交或回滾事務的決定必須產生統一的結果(所有提交或所有回滾).

因爲存在事務機制,能夠保證每一個獨立節點上的數據操做能夠知足ACID。可是,相互獨立的節點之間沒法準確的知道其餘節點中的事務執行狀況.

讓分佈式部署的多臺機器中的數據保持一致性,那麼就要保證在全部節點的數據寫操做,要不所有都執行,要麼所有的都不執行。可是,一臺機器在執行本地事務的時候沒法知道其餘機器中的本地事務的執行結果。因此他也就不知道本次事務到底應該commit仍是 roolback。因此,常規的解決辦法就是引入一個「協調者」的組件來統一調度全部分佈式節點的執行。

XA規範

 X/Open DTP 模型( 1994 )包括:應用程序( AP )、事務管理器( TM )、資源管理器( RM )、通訊資源管理器( CRM )四部分.。

通常,常見的事務管理器( TM )是交易中間件,常見的資源管理器( RM )是數據庫,常見的通訊資源管理器( CRM )是消息中間件。

一般把一個數據庫內部的事務處理,如對多個表的操做,做爲本地事務看待。數據庫的事務處理對象是本地事務,而分佈式事務處理的對象是全局事務。 所謂全局事務,是指分佈式事務處理環境中,多個數據庫可能須要共同完成一個工做,這個工做便是一個全局事務

例如,一個事務中可能更新幾個不一樣的數據庫。對數據庫的操做發生在系統的各處但必須所有被提交或回滾。此時一個數據庫對本身內部所作操做的提交不只依賴自己操做是否成功,還要依賴與全局事務相關的其它數據庫的操做是否成功,若是任一數據庫的任一操做失敗,則參與此事務的全部數據庫所作的全部操做都必須回滾。 通常狀況下,某一數據庫沒法知道其它數據庫在作什麼,所以,在一個 DTP 環境中,交易中間件是必需的,由它通知和協調相關數據庫的提交或回滾。而一個數據庫只將其本身所作的操做(可恢復)影射到全局事務中。

二階提交協議和三階提交協議就是根據這一思想衍生出來的。能夠說二階段提交其實就是實現XA分佈式事務的關鍵(確切地說:兩階段提交主要保證了分佈式事務的原子性:即全部結點要麼全作要麼全不作)。

 

 3.1 二階段提交

兩個階段是指:第一階段:準備階段(投票階段)和第二階段:提交階段(執行階段)

準備階段

事務協調者(事務管理器)給每一個參與者(資源管理器)發送Prepare消息,每一個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的redo和undo日誌,但不提交。

  1. 協調者節點向全部參與者節點詢問是否能夠執行提交操做(vote),並開始等待各參與者節點的響應。
  2. 參與者節點執行詢問發起爲止的全部事務操做,並將Undo信息和Redo信息寫入日誌。
  3. 各參與者節點響應協調者節點發起的詢問。若是參與者節點的事務操做實際執行成功,則它返回一個」贊成」消息;若是參與者節點的事務操做實際執行失敗,則它返回一個」停止」消息。

提交階段

若是協調者收到了參與者的失敗消息或者超時,直接給每一個參與者發送回滾(Rollback)消息;不然,發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操做,釋放全部事務處理過程當中使用的鎖資源。當協調者節點從全部參與者節點得到的相應消息都爲」贊成」時:

  1. 協調者節點向全部參與者節點發出」正式提交(commit)」的請求,
  2. 參與者節點正式完成操做,並釋放在整個事務期間內佔用的資源
  3. 參與者節點向協調者節點發送」完成」消息
  4. 協調者節點受到全部參與者節點反饋的」完成」消息後,完成事務

當收到參與節點的終止消息的時候,步驟與上面的相似。

二階段提交的問題

  1. 同步阻塞問題。執行過程當中,全部參與節點都是事務阻塞型的。當參與者佔有公共資源時,其餘第三方節點訪問公共資源不得不處於阻塞狀態。
  2. 單點故障。因爲協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。尤爲在第二階段,協調者發生故障,那麼全部的參與者還都處於鎖定事務資源的狀態中,而沒法繼續完成事務操做。(若是是協調者掛掉,能夠從新選舉一個協調者,可是沒法解決由於協調者宕機致使的參與者處於阻塞狀態的問題)
  3. 數據不一致。在二階段提交的階段二中,當協調者向參與者發送commit請求以後,發生了局部網絡異常或者在發送commit請求過程當中協調者發生了故障,這回致使只有一部分參與者接受到了commit請求。而在這部分參與者接到commit請求以後就會執行commit操做。可是其餘部分未接到commit請求的機器則沒法執行事務提交。因而整個分佈式系統便出現了數據部一致性的現象。
  4. 二階段沒法解決的問題:協調者再發出commit消息以後宕機,而惟一接收到這條消息的參與者同時也宕機了。那麼即便協調者經過選舉協議產生了新的協調者,這條事務的狀態也是不肯定的,沒人知道事務是否被已經提交。

3.2 三階段提交

三階段提交有兩個改動點:

  1. 引入超時機制。同時在協調者和參與者中都引入超時機制。
  2. 在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段以前各參與節點的狀態是一致的。

CanCommit階段

3PC的CanCommit階段其實和2PC的準備階段很像。協調者向參與者發送commit請求,參與者若是能夠提交就返回Yes響應,不然返回No響應。

PreCommit階段

協調者根據參與者的反應狀況來決定是否能夠記性事務的PreCommit操做。根據響應狀況,有如下兩種可能。

假如協調者從全部的參與者得到的反饋都是Yes響應,那麼就會執行事務的預執行。

假若有任何一個參與者向協調者發送了No響應,或者等待超時以後,協調者都沒有接到參與者的響應,那麼就執行事務的中斷。

 

doCommit階段

該階段進行真正的事務提交,也能夠分爲如下兩種狀況。

執行提交:

  1. 發送提交請求 協調接收到參與者發送的ACK響應,那麼他將從預提交狀態進入到提交狀態。並向全部參與者發送doCommit請求。
  2. 事務提交 參與者接收到doCommit請求以後,執行正式的事務提交。並在完成事務提交以後釋放全部事務資源。
  3. 響應反饋 事務提交完以後,向協調者發送Ack響應。
  4. 完成事務 協調者接收到全部參與者的ack響應以後,完成事務。

中斷事務 協調者沒有接收到參與者發送的ACK響應(多是接受者發送的不是ACK響應,也可能響應超時),那麼就會執行中斷事務。

  1. 發送中斷請求 協調者向全部參與者發送abort請求
  2. 事務回滾 參與者接收到abort請求以後,利用其在階段二記錄的undo信息來執行事務的回滾操做,並在完成回滾以後釋放全部的事務資源。
  3. 反饋結果 參與者完成事務回滾以後,向協調者發送ACK消息
  4. 中斷事務 協調者接收到參與者反饋的ACK消息以後,執行事務的中斷。

在doCommit階段,若是參與者沒法及時接收到來自協調者的doCommit或者rebort請求時,會在等待超時以後,會繼續進行事務的提交。(其實這個應該是基於機率來決定的,當進入第三階段時,說明參與者在第二階段已經收到了PreCommit請求,那麼協調者產生PreCommit請求的前提條件是他在第二階段開始以前,收到全部參與者的CanCommit響應都是Yes。(一旦參與者收到了PreCommit,意味他知道你們其實都贊成修改了)因此,一句話歸納就是,當進入第三階段時,因爲網絡超時等緣由,雖然參與者沒有收到commit或者abort響應,可是他有理由相信:成功提交的概率很大。 )

也就是說即便第三階段超時,可是因爲第二階段的存在,所以有理由認爲,各個參與者是能夠提交成功的。

3.3 2PC與3PC的區別

相對於2PC,3PC主要解決的單點故障問題,並減小阻塞,由於一旦參與者沒法及時收到來自協調者的信息以後,他會默認執行commit。而不會一直持有事務資源並處於阻塞狀態。可是這種機制也會致使數據一致性問題,由於,因爲網絡緣由,協調者發送的abort響應沒有及時被參與者接收到,那麼參與者在等待超時以後執行了commit操做。這樣就和其餘接到abort命令並執行回滾的參與者之間存在數據不一致的狀況。不管是二階段提交仍是三階段提交都沒法完全解決分佈式的一致性問題。世上只有一種一致性算法,那就是Paxos,全部其餘一致性算法都是Paxos算法的不完整版。

相關文章
相關標籤/搜索