理解:事務兩階段提交和三階段提交(2PC、3PC)

目錄

兩階段提交(2PC)

準備階段:

提交階段:

2PC存在的問題:

三階段提交(3PC)

CanCommit:

PreCommit(如果CanCommit階段中所有參與者都返回“Yes”)

DoCommit

3PC存在的問題:

3PC在2PC上的改動點:


兩階段提交(2PC)

圖片來源:https://medium.com/@balrajasubbiah/consensus-two-phase-and-three-phase-commits-4e35c1a435ac

 

準備階段:

1.協調者:向所有參與者發出“Request-to-Prepare”,進入提交階段。

2.參與者:收到協調者的“Request-to-Prepare”,執行事務操作。

(1)事務執行成功,並寫入Undo log和Redo log,返回“Prepared”。

(2)事務執行失敗,返回“abort”。

 

提交階段:

1.協調者:有超時機制
(1)如果所有參與者應答“Prepared”,協調者向所有參與者發出“Commit”。等待所有參與者返回“Done”,結束事務。

(2)如果存在參與者應答“Abort”,協調者向所有參與者發出“Rollback”。等待所有參與者返回“Done”,結束事務。

(3)如果到達協調者的超時時間,仍未收到所有參與者的應答,則向參與者發出“Rollback”。

2.參與者:

(1)收到“Commit”,完成操作,並釋放在整個事務期間內佔用的資源和鎖,返回“Done”。

(2)收到“Rollback”,參與者利用之前寫入的Undo信息執行回滾,並釋放在整個事務期間內佔用的資源,返回“Done”。

 

2PC存在的問題:

1.參與者無超時機制:一旦參與者故障,可能導致事務資源一直被鎖定(同步阻塞);協調者故障,導致所有參與者一直鎖定事務資源(單點故障)。

2.數據不一致:在提交階段,部分參與者收到commit並執行commit,部分參與者因爲網絡等問題沒收到消息導致無法執行事務提交。

3.無法解決:在提交階段,協調者在發出第一個commit後宕機,唯一收到此commit消息的參與者也宕機。協調者重新選舉出來後也不知道事務應該提交還是不提交。

 

三階段提交(3PC)

圖片來源:https://en.wikipedia.org/wiki/Three-phase_commit_protocol

 

狀態扭轉

圖片來源:https://developer.jboss.org/wiki/Three-phaseCommitProtocol

 

CanCommit:

1.協調者:協調者向所有參與者詢問“CanCommit”,協調者變更爲waiting狀態,等待參與者應答

(1)所有參與者返回“Yes”,協調者進入PreCommit階段。

(2)有參與者返回“No”,協調者中斷事務,併發送“abort”給所有參與者,變更爲“aborted”狀態。

(3)協調者等待超時,協調者中斷事務,併發送“abort”給所有參與者,變更爲“aborted”狀態。

2.參與者:判斷是否能提交事務

(1)能提交事務,返回“Yes”,變更爲“waiting”狀態。

(2)不能提交事務,返回“No”,變更爲“abored”狀態。

(3)接受到協調者的“abort”請求,變更爲“aborted”狀態。

 

PreCommit(如果CanCommit階段中所有參與者都返回“Yes”)

1.協調者:發送“PrepareCommit”給所有參與者,協調者進入pre-commit狀態,等待參與者應答。

(1)所有參與者都返回“ack”,進入DoCommit階段。

(2)有參與者返回“abort”後,執行事務的中斷,協調者向所有參與者發送“abort”,變更爲“aborted”狀態。

(3)協調者等待參與者應答的時候,協調者發生超時,協調者會中斷事務,協調者向所有參與者發送“abort”,變更爲“aborted”狀態。

2.參與者:執行事務操作,並將undo和redo信息記錄到事務日誌中

(1)執行成功,返回“ack”,變更爲“pre-commit”狀態。

(2)執行失敗,返回“abort”,變更爲“aborted”狀態。

(3)等待協調者的“PrepareCommit”超時,返回“abort”,變更爲“aborted”狀態。

(4)接收到協調者的“absort”請求,中斷事務,變更爲“aborted”狀態。

 

DoCommit

1.協調者:如果所有參與者在PreCommit階段都返回“ack”,則發送“commit”給所有參與者,協調者進入“commited”狀態。

(1)協調者收到所有參與者的“ack”應答,事務結束。

(2)協調者等待參與者“ack”應答超時,協調者中斷事務,發送“abort”給所有參與者,進入“aborted”狀態。

2.協調者:如果有參與者返回“abort”,則發送“abort”給所有參與者,中斷事務,協調者進入“aborted”狀態。

3.參與者:根據協調者發出的命令進行操作

(1)參與者收到協調者的“commit”,執行事務提交,並釋放所有的資源和鎖,參與者進入“commited”狀態。返回“ack”。

(2)參與者收到協調者的“abort”,根據undo日誌進行回滾,並釋放所有的資源和鎖,參與者進入“aborted”狀態,返回“ack”。

(3)參與者爲“pre-commit”狀態,沒有收到協調者的“commit”或“abort”,會在等待超時後,提交事務(可能出現數據一致性的問題,例如參與者沒有收到的消息是“abort”)。

 

3PC存在的問題:

1.數據不一致:在DoCommit階段,如果因爲網絡問題,協調者發出的abort沒有及時被參與者接收。這時候參與者最終執行了commit,就會引發數據不一致的問題。

2.需要更多的通訊次數,實現複雜

 

3PC在2PC上的改動點:

  • 在協調者和參與者中都引入超時機制(處理同步阻塞、單點故障問題)。
  • 將2PC的“準備階段”切分成:CanCommit、DoCommit。在CanCommit階段中儘早給出事務是否可以執行的判斷,減少資源佔用,提高吞吐量。
  • 在DoCommit階段,即使協調者宕機,如果參與者不是abort和commited狀態,就只能是pre-commit狀態,最終也會提交事務。因爲當該參與者是“pre-commit”狀態時,意味着所有參與者都在CanCommit階段中應答了,很大概率是可以成功執行事務的。因爲在這3個階段任意一個階段中,如果任意一個參與者故障、超時、不能執行事務,協調者都會發送abort給所有參與者中斷事務。

參考:

https://developer.jboss.org/wiki/Three-phaseCommitProtocol

https://en.wikipedia.org/wiki/Two-phase_commit_protocol

https://en.wikipedia.org/wiki/Three-phase_commit_protocol

http://www.hollischuang.com/archives/681

https://www.hollischuang.com/archives/1580

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章