天天看點

分布式事務-2PC和3PC

提到2PC/3PC首先想到的是它是一緻性協定,而且經常把它和Paxos協定放在一起比較,并且經常看到這樣的說法"世上隻有一種一緻性算法,那就是Paxos",2PC/3PC并不是嚴格意義上的一緻性協定,很少被用在處理一緻性上;但另一方面又經常看到2PC/3PC和分布式事務放在一起讨論,并且大部分的關系型資料庫通過兩階段送出(2 Phase Commit 2PC)算法來完成分布式事務。

先大緻了解一下分布式事務和一緻性

分布式事務

分布式事務:是指會涉及到操作多個資料庫的事務。其實就是将對同一庫事務的概念擴大到了對多個庫的事務。目的是為了保證分布式系統中的資料一緻性。分布式事務處理的關鍵是必須有一種方法可以知道事務在任何地方所做的所有動作,送出或復原事務的決定必須産生統一的結果(全部送出或全部復原)。

兩類一緻性

說到一緻性大家更多的應該想到的是CAP裡面的A表示的一緻性(一個資料分片的多個副本之間的資料一緻性)就是資料一緻性;但我覺得還可以有另外一種了解就是ACID中的A(一個事務在執行之前和執行之後,資料庫都必須處于一緻性狀态)就是狀态一緻性或者叫操作原子性。

其實這裡說的狀态一緻性或者叫操作原子性就是分布式事務,大範圍來講,其實一緻性其實是包含分布式事務的,隻不過我們提到一緻性更多情況下講的就是資料一緻性。

2PC/3PC由來:XA規範

X/Open 組織(即現在的 Open Group )定義了分布式事務處理模型。 X/Open DTP 模型( 1994 )包括應用程式( AP )、事務管理器( TM )、資料總管( RM )、通信資料總管( CRM )四部分。一般,常見的事務管理器( TM )是交易中間件,常見的資料總管( RM )是資料庫,常見的通信資料總管( CRM )是消息中間件。 

XA 就是 X/Open DTP 定義的交易中間件與資料庫之間的接口規範(即接口函數),交易中間件用它來通知資料庫事務的開始、結束以及送出、復原等。 XA 接口函數由資料庫廠商提供。 

二階送出協定和三階送出協定就是根據這一思想衍生出來的。可以說二階段送出其實就是實作XA分布式事務的關鍵(确切地說:兩階段送出主要保證了分布式事務的原子性:即所有結點要麼全做要麼全不做)。

是以大部分的關系型資料庫通過兩階段送出(2 Phase Commit 2PC)算法來完成分布式事務就不足為奇了。

讨論總結

2PC/3PC送出其實就是實作XA分布式事務的關鍵,而分布式事務從廣義上來講也是一緻性的一種表現,是以2PC/3PC也可以叫一緻性協定;其實在表示資料一緻性的環境下,2PC/3PC代表的含義:要麼所有備份資料同時更改某個值,要麼都不更改,以此來達到資料的強一緻性。在真實的應用中,盡管有系統使用2PC/3PC協定來作為資料一緻性協定,但是比較少見,更多的是作為實作資料更新原子性手段出現。

為什麼2PC/3PC沒有被廣泛用在保證資料的一緻性上,主要原因應該還是它本身的缺陷,所有經常看到這句話:there is only one consensus protocol, and that’s Paxos” – all other approaches are just broken versions of Paxos. 意即世上隻有一種一緻性算法,那就是Paxos。

下面大概介紹一下2PC/3PC

2PC/3PC

2PC/3PC全稱:Two/Three Phase Commit,中文名叫叫兩階段/三階段送出;為了使基于分布式系統架構下的所有節點在進行事務處理的過程中能夠ACID特性而設計的一種算法,需要引入一個作為協調者的元件來統一掌控所有節點(稱作參與者)的操作結果并最終訓示這些節點是否要把操作結果進行真正的送出兩階段送出的算法如下:

第一階段:送出事務階段(投票階段)

1.事務詢問:協調者會問所有的參與者結點,是否可以執行送出操作

2.執行事務:各個參與者執行事務操作 如:資源上鎖,将Undo和Redo資訊記入事務日志中

3.參與者向協調者回報事務詢問的響應:如果參與者成功執行了事務操作,回報給協調者Yes響應,否則No響應

第二階段:執行事務送出(執行階段)

假如協調者從所有的參與者獲得的回報都是Yes響應,那麼就會執行事務送出

1.發送送出請求:協調者向參與者發送Commit請求

2.事務送出:參與者接受到Commit請求後,會正式執行事務送出操作,并在完成送出之後釋放事務資源

3.回報事務送出結果:參與者在完成事務送出之後,向協調者發送Ack消息

4.完成事務:協調者接受到所有參與者回報的Ack消息後,完成事務

假如任何一個參與者向協調者回報了No響應,或者在等待逾時之後,協調者尚無接收到所有參與者的回報資訊,那麼就會中斷事務

1.發送復原請求:協調者向參與者發送Rollback請求

2.事務復原:參與者利用Undo資訊來執行事務復原,并釋放事務資源

3.回報事務復原結果:參與者在完成事務復原之後,向協調者發送Ack消息

4.中斷事務:協調者接收到所有參與者回報的Ack消息之後,中斷事務

網上看來的西方教堂結婚一個橋段很好的描述了2PC協定:

1.牧師分别問新郎和新娘:你是否願意……不管生老病死……(投票階段)

2.當新郎和新娘都回答願意後(鎖定一生的資源),牧師就會說:我宣布你們……(執行階段)

2PC存在的問題

1.阻塞問題

二階段送出的第一階段中,協調者需要等待參與者的響應,如果沒有接收到任意參與者的響應,這時候進入等待狀态,而其他正常發送響應的參與者,将進入阻塞狀态,将無法進行其他任何操作,隻有等待逾時中斷事務,極大的限制了系統的性能。

2.單點問題

協調者處于一個中心的位置,一旦出現問題,那麼整個二階段送出将無法運轉,更為嚴重的是,如果協調者在階段二中出現問題的話,那麼其他參與者将會一直處于鎖定事務資源的狀态中,将無法繼續完成操作

以上提到的2個問題都在3PC中得到了解決

1.解決阻塞問題:将2PC中的第一階段一分為二,提供了一個CanCommit階段,此階段并不鎖定資源,這樣可以大幅降低了阻塞機率

2.解決單點問題:在參與者這邊也引入了逾時機制

3PC

3PC是2PC的改進版本,将2PC的第一階段:送出事務階段一分為二,形成了CanCommit、PreCommit和doCommit三個階段組成的事務處理協定,具體看一張流程圖(來源網上):

分布式事務-2PC和3PC

三段送出的核心理念是:在詢問的時候并不鎖定資源,除非所有人都同意了,才開始鎖資源。

3PC具體的流程步驟就不在描述了,在二階段的基礎上加了事務詢問的過程(CanCommit)

3PC雖然解決了2PC存在的2個問題,但是不管是2PC還是3PC都存在資料一緻性的問題:

2PC:比如協調者在隻給部分參與者發送了Commit請求,那就會出現部分參與者執行了Commit,部分沒有送出,出現不一緻問題。

3PC:一旦參與者無法及時收到來自協調者的資訊之後,他會預設執行commit。而不會一直持有事務資源并處于阻塞狀态,但是這種機制也會導緻資料一緻性問題。

總結

2PC/3PC用來處理分布式事務: 能夠很好的提供強一緻性和強事務性,但相對來說延遲比較高,比較适合傳統的單體應用,在同一個方法中存在跨庫操作的情況,不适合高并發和高性能要求的場景。

2PC/3PC用來處理資料一緻性:很少使用,更多的是Paxos或者基于Paxos的變體。

轉載:ksfzhaohui

繼續閱讀