分布式事务理论-二阶段提交(Two-phase Commit)
1 2PC
兩階段提交協(xié)議為了保證分布在不同節(jié)點(diǎn)上的分布式事務(wù)的一致性,我們需要引入一個(gè)協(xié)調(diào)者來管理所有的節(jié)點(diǎn),負(fù)責(zé)各個(gè)本地資源的提交和回滾,并確保這些節(jié)點(diǎn)正確提交操作結(jié)果,若提交失敗則放棄事務(wù)。
2.1 XA 協(xié)議
XA 是一個(gè)分布式事務(wù)協(xié)議,規(guī)定了事務(wù)管理器和資源管理器接口。因此,XA 協(xié)議可以分為兩部分,即事務(wù)管理器和本地資源管理器。
- 事務(wù)管理器作為協(xié)調(diào)者,負(fù)責(zé)各個(gè)本地資源的提交和回滾;
- 資源管理器就是分布式事務(wù)的參與者.其中資源管理通常是 數(shù)據(jù)庫。
基于 XA 協(xié)議的二階段提交方法中,二階段提交協(xié)議(The two-phase commit protocol,2PC),用于保證分布式系統(tǒng)中事務(wù)提交時(shí)的數(shù)據(jù)一致性,是 XA 在全局事務(wù)中用于協(xié)調(diào)多個(gè)資源的機(jī)制。
2.2 二階段提交
分為投票和提交兩個(gè)階段。
?
投票為第一階段:
- 1 協(xié)調(diào)者(Coordinator,即事務(wù)管理器)會(huì)向事務(wù)的參與者(Cohort,即本地資源管理器)發(fā)起執(zhí)行操作的 CanCommit 請(qǐng)求,并等待參與者的響應(yīng).
- 2 參與者接收到請(qǐng)求后,會(huì)執(zhí)行請(qǐng)求中的事務(wù)操作,記錄日志信息(包含事務(wù)執(zhí)行前的鏡像),同時(shí)鎖定當(dāng)前記錄。參與者執(zhí)行成功,則向協(xié)調(diào)者發(fā)送“Yes”消息,表示同意操作;若不成功,則發(fā)送“No”消息,表示終止操作。
- 3 當(dāng)所有的參與者都返回了操作結(jié)果(Yes 或 No 消息)后,系統(tǒng)進(jìn)入了提交階段。
提為第二階段:
協(xié)調(diào)者會(huì)根據(jù)所有參與者返回的信息向參與者發(fā)送 DoCommit 或 DoAbort 指令
- 若協(xié)調(diào)者收到的都是“Yes”消息,則向參與者發(fā)送“DoCommit”消息,參與者會(huì)完成剩余的操作并釋放資源,然后向協(xié)調(diào)者返回“HaveCommitted”消息;
- 如果協(xié)調(diào)者收到的消息中包含“No”消息,則向所有參與者發(fā)送“DoAbort”消息,此時(shí)發(fā)送“Yes”的參與者則會(huì)根據(jù)之前執(zhí)行操作時(shí)的回滾日志對(duì)操作進(jìn)行回滾,然后所有參與者會(huì)向協(xié)調(diào)者發(fā)送“HaveCommitted”消息;
- 協(xié)調(diào)者接收到“HaveCommitted”消息,就意味著整個(gè)事務(wù)結(jié)束了。
2.3 2PC問題
同步阻塞問題:二階段提交算法在執(zhí)行過程中,所有參與節(jié)點(diǎn)都是事務(wù)阻塞型的。也就是說,當(dāng)本地資源管理器占有臨界資源時(shí),其他資源管理器如果要訪問同一臨界資源,會(huì)處于阻塞狀態(tài)。
協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞問題:基于 XA 的二階段提交算法類似于集中式算法,一旦事務(wù)管理器發(fā)生故障,整個(gè)系統(tǒng)都處于停滯狀態(tài)。尤其是在提交階段,一旦事務(wù)管理器發(fā)生故障,資源管理器會(huì)由于等待管理器的消息,而一直鎖定事務(wù)資源,導(dǎo)致整個(gè)系統(tǒng)被阻塞。
數(shù)據(jù)不一致問題:在提交階段,當(dāng)協(xié)調(diào)者向參與者發(fā)送 DoCommit 請(qǐng)求之后,如果發(fā)生了局部網(wǎng)絡(luò)異常,或者在發(fā)送提交請(qǐng)求的過程中協(xié)調(diào)者發(fā)生了故障,就會(huì)導(dǎo)致只有一部分參與者接收到了提交請(qǐng)求并執(zhí)行提交操作,但其他未接到提交請(qǐng)求的那部分參與者則無法執(zhí)行事務(wù)提交。于是整個(gè)分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)不一致的問題。
二階段無法解決的問題:協(xié)調(diào)者再發(fā)出DoCommit 消息之后宕機(jī),而唯一接收到這條消息的參與者同時(shí)也宕機(jī)了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者,這條事務(wù)的狀態(tài)也是不確定的,沒人知道事務(wù)是否被已經(jīng)提交。
3 3PC
三階段提交協(xié)議(Three-phase commit protocol,3PC),是對(duì)二階段提交(2PC)的改進(jìn)。為了解決兩階段提交的同步阻塞和數(shù)據(jù)不一致問題,三階段提交引入了超時(shí)機(jī)制和準(zhǔn)備階段。
超時(shí)機(jī)制
同時(shí)在協(xié)調(diào)者和參與者中引入超時(shí)機(jī)制。如果協(xié)調(diào)者或參與者在規(guī)定的時(shí)間內(nèi)沒有接收到來自其他節(jié)點(diǎn)的響應(yīng),就會(huì)根據(jù)當(dāng)前的狀態(tài)選擇提交或者終止整個(gè)事務(wù)。
準(zhǔn)備階段
在第一階段和第二階段中間引入了一個(gè)準(zhǔn)備階段,也就是在提交階段之前,加入了一個(gè)預(yù)提交階段。在預(yù)提交階段排除一些不一致的情況,保證在最后提交之前各參與節(jié)點(diǎn)的狀態(tài)是一致的。
3.1 三階段提交
?
CanCommit 階段
協(xié)調(diào)者向參與者發(fā)送請(qǐng)求操作(CanCommit 請(qǐng)求),詢問參與者是否可以執(zhí)行事務(wù)提交操作,然后等待參與者的響應(yīng);參與者收到 CanCommit 請(qǐng)求之后,回復(fù) Yes,表示可以順利執(zhí)行事務(wù);否則回復(fù) No。(我個(gè)人理解類似做TCC中Try操作)
?
PreCommit 階段
協(xié)調(diào)者根據(jù)參與者的回復(fù)情況,來決定是否可以進(jìn)行 PreCommit 操作 或 中斷事務(wù)。
如果所有參與者回復(fù)的都是“Yes”,那么協(xié)調(diào)者就會(huì)執(zhí)行事務(wù)的預(yù)執(zhí)行:
- 發(fā)送預(yù)提交請(qǐng)求。協(xié)調(diào)者向參與者發(fā)送 PreCommit 請(qǐng)求,進(jìn)入預(yù)提交階段。
- 事務(wù)預(yù)提交。參與者接收到 PreCommit 請(qǐng)求后執(zhí)行事務(wù)操作,并將 Undo 和 Redo 信息記錄到事務(wù)日志中,同時(shí)鎖定當(dāng)前記錄。
- 響應(yīng)反饋。如果參與者成功執(zhí)行了事務(wù)操作,則返回 ACK 響應(yīng),同時(shí)開始等待最終指令
如果任何一個(gè)參與者向協(xié)調(diào)者發(fā)送了“No”消息,或者等待超時(shí)之后,協(xié)調(diào)者都沒有收到參與者的響應(yīng),就執(zhí)行中斷事務(wù)的操作:
- 發(fā)送中斷請(qǐng)求。協(xié)調(diào)者向所有參與者發(fā)送“Abort”消息。
- 中斷事務(wù)。參與者收到“Abort”消息之后,或超時(shí)后仍未收到協(xié)調(diào)者的消息,執(zhí)行事務(wù)的中斷操作。
DoCommit 階段
協(xié)調(diào)者根據(jù)參與者的回復(fù)情況,來決定是否可以進(jìn)行 DoCommit 操作 或 中斷事務(wù)。
如果所有參與者回復(fù)的都是“Yes”,那么協(xié)調(diào)者就會(huì)執(zhí)行事務(wù)的提交:
- 發(fā)送提交請(qǐng)求。協(xié)調(diào)者接收到所有參與者發(fā)送的 Ack 響應(yīng),從預(yù)提交狀態(tài)進(jìn)入到提交狀態(tài),并向所有參與者發(fā)送 DoCommit 消息。
- 事務(wù)提交。參與者接收到 DoCommit 消息之后,正式提交事務(wù)。完成事務(wù)提交之后,釋放所有鎖住的資源。
- 響應(yīng)反饋。參與者提交完事務(wù)之后,向協(xié)調(diào)者發(fā)送 Ack 響應(yīng)。
- 完成事務(wù)。協(xié)調(diào)者接收到所有參與者的 Ack 響應(yīng)之后,完成事務(wù)。
如果任何一個(gè)參與者向協(xié)調(diào)者發(fā)送了“No”消息,或者協(xié)調(diào)者等待超時(shí)之后,協(xié)調(diào)者都沒有收到參與者的響應(yīng),就執(zhí)行中斷事務(wù)的操作:
- 發(fā)送中斷請(qǐng)求。協(xié)調(diào)者向所有參與者發(fā)送 Abort 請(qǐng)求。
- 事務(wù)回滾。參與者接收到 Abort 消息之后,利用其在 PreCommit 階段記錄的 Undo 信息執(zhí)行事務(wù)的回滾操作,并釋放所有鎖住的資源。
- 反饋結(jié)果。參與者完成事務(wù)回滾之后,向協(xié)調(diào)者發(fā)送 Ack 消息。
- 中斷事務(wù)。協(xié)調(diào)者接收到參與者反饋的 Ack 消息之后,執(zhí)行事務(wù)的中斷,并結(jié)束事務(wù)。
 。
當(dāng)參與者PreCommit 階段向協(xié)調(diào)者發(fā)送 Ack 消息后,如果長(zhǎng)時(shí)間沒有得到協(xié)調(diào)者的響應(yīng),在默認(rèn)情況下,參與者會(huì)自動(dòng)將超時(shí)的事務(wù)進(jìn)行提交,不會(huì)像兩階段提交那樣被阻塞住
?
3.2 如何解決協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞
由于存在超時(shí)機(jī)制,即使協(xié)調(diào)者發(fā)生故障,參與者無法及時(shí)收到來自協(xié)調(diào)者的信息之后,他會(huì)默認(rèn)執(zhí)行commit。避免參與者長(zhǎng)期阻塞。
3.3 同步阻塞問題
3PC會(huì)在2階段到3階段間阻塞,2PC會(huì)在1階段到2階段整個(gè)事務(wù)過程中阻塞,因而總體來說3PC并不能不阻塞,只是最大限度減少了阻塞的時(shí)間。同時(shí)安裝5.2也能夠解決協(xié)調(diào)者單點(diǎn)故障導(dǎo)致參與者長(zhǎng)期阻塞的問題
3.4 數(shù)據(jù)不一致問題
3PC和2PC都無法解決數(shù)據(jù)一致的問題,不過3PC存在超時(shí)會(huì)通過超時(shí)保證協(xié)調(diào)者和參與者在提交階段無法通信過程中最終一致,而不需人工介入。
4 小結(jié)
?
?
總結(jié)
以上是生活随笔為你收集整理的分布式事务理论-二阶段提交(Two-phase Commit)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Gossip协议详解
- 下一篇: decltype 和 auto
