分散式事務-2PC和3PC

加瓦一枚發表於2018-12-18

提到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三個階段組成的事務處理協議,具體看一張流程圖(來源網上):

三段提交的核心理念是:在詢問的時候並不鎖定資源,除非所有人都同意了,才開始鎖資源。
3PC具體的流程步驟就不在描述了,在二階段的基礎上加了事務詢問的過程(CanCommit)

3PC雖然解決了2PC存在的2個問題,但是不管是2PC還是3PC都存在資料一致性的問題:
2PC:比如協調者在只給部分參與者傳送了Commit請求,那就會出現部分參與者執行了Commit,部分沒有提交,出現不一致問題。
3PC:一旦參與者無法及時收到來自協調者的資訊之後,他會預設執行commit。而不會一直持有事務資源並處於阻塞狀態,但是這種機制也會導致資料一致性問題。

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

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

 

轉載:ksfzhaohui

相關文章