二階段提交2PC(2-phase commit)
為了使基于分布式系統(tǒng)架構(gòu)下的所有節(jié)點在進行事務(wù)提交時保持一致性而設(shè)計的一種算法。通常,二階段提交也被稱為是一種協(xié)議(Protocol)。在分布式系統(tǒng)中,每個節(jié)點雖然可以知曉自己的操作時成功或者失敗,卻無法知道其他節(jié)點的操作的成功或失敗。當一個事務(wù)跨越多個節(jié)點時,為了保持事務(wù)的ACID特性,需要引入一個作為協(xié)調(diào)者的組件來統(tǒng)一掌控所有節(jié)點(稱作參與者)的操作結(jié)果并最終指示這些節(jié)點是否要把操作結(jié)果進行真正的提交(比如將更新后的數(shù)據(jù)寫入磁盤等等)。因此,二階段提交的算法思路可以概括為: 參與者將操作成敗通知協(xié)調(diào)者,再由協(xié)調(diào)者根據(jù)所有參與者的反饋情報決定各參與者是否要提交操作還是中止操作。
優(yōu)點: 盡量保證了數(shù)據(jù)的強一致,適合對數(shù)據(jù)強一致要求很高的關(guān)鍵領(lǐng)域。(其實也不能100%保證強一致)
缺點: 實現(xiàn)復(fù)雜,犧牲了一部分可用性來換取的一致性,對性能影響較大,不適合高并發(fā)高性能場景,
- 二階段提交算法的成立基于以下假設(shè):
* 該分布式系統(tǒng)中,存在一個節(jié)點作為協(xié)調(diào)者(Coordinator),其他節(jié)點作為參與者(Cohorts)。且節(jié)點之間可以進行網(wǎng)絡(luò)通信。
* 所有節(jié)點都采用預(yù)寫式日志,且日志被寫入后即被保持在可靠的存儲設(shè)備上,即使節(jié)點損壞不會導(dǎo)致日志數(shù)據(jù)的消失。
* 所有節(jié)點不會永久性損壞,即使損壞后仍然可以恢復(fù)。
第一階段(提交請求階段)
協(xié)調(diào)者節(jié)點向所有參與者節(jié)點詢問是否可以執(zhí)行提交操作,并開始等待各參與者節(jié)點的響應(yīng)。
參與者節(jié)點執(zhí)行詢問發(fā)起為止的所有事務(wù)操作,并將Undo信息和Redo信息寫入日志。
各參與者節(jié)點響應(yīng)協(xié)調(diào)者節(jié)點發(fā)起的詢問。如果參與者節(jié)點的事務(wù)操作實際執(zhí)行成功,則它返回一個"同意"消息;如果參與者節(jié)點的事務(wù)操作實際執(zhí)行失敗,則它返回一個"中止"消息。
有時候,第一階段也被稱作投票階段,即各參與者投票是否要繼續(xù)接下來的提交操作。
第二階段(提交執(zhí)行階段)
成功
當協(xié)調(diào)者節(jié)點從所有參與者節(jié)點獲得的相應(yīng)消息都為"同意"時:
- 協(xié)調(diào)者節(jié)點向所有參與者節(jié)點發(fā)出"正式提交"的請求。
- 參與者節(jié)點正式完成操作,并釋放在整個事務(wù)期間內(nèi)占用的資源。
- 參與者節(jié)點向協(xié)調(diào)者節(jié)點發(fā)送"完成"消息。
- 協(xié)調(diào)者節(jié)點收到所有參與者節(jié)點反饋的"完成"消息后,完成事務(wù)。
失敗
如果任一參與者節(jié)點在第一階段返回的響應(yīng)消息為"終止",或者 協(xié)調(diào)者節(jié)點在第一階段的詢問超時之前無法獲取所有參與者節(jié)點的響應(yīng)消息時:
協(xié)調(diào)者節(jié)點向所有參與者節(jié)點發(fā)出"回滾操作"的請求。
- 參與者節(jié)點利用之前寫入的Undo信息執(zhí)行回滾,并釋放在整個事務(wù)期間內(nèi)占用的資源。
- 參與者節(jié)點向協(xié)調(diào)者節(jié)點發(fā)送"回滾完成"消息。
- 協(xié)調(diào)者節(jié)點收到所有參與者節(jié)點反饋的"回滾完成"消息后,取消事務(wù)。
- 有時候,第二階段也被稱作完成階段,因為無論結(jié)果怎樣,協(xié)調(diào)者都必須在此階段結(jié)束當前事務(wù)。