聲明:本文屬于《從Paxos到Zookeeper 分布式一致性原理與實(shí)踐》的學(xué)習(xí)筆記。內(nèi)容大部分源自此書。
在對(duì)一個(gè)分布式系統(tǒng)進(jìn)行架構(gòu)設(shè)計(jì)的過程中,往往會(huì)在系統(tǒng)的可用性與數(shù)據(jù)一致性之間進(jìn)行反復(fù)權(quán)衡,于是就產(chǎn)生了一系列的一致性協(xié)議。
本文將介紹其中的2PC和3PC。2PC即Two-Phase Commit,譯為二階段提交協(xié)議。3PC即Three-Phase Commit,譯為三階段提交協(xié)議。
引入?yún)f(xié)調(diào)者的概念:
在分布式系統(tǒng)中,每個(gè)機(jī)器節(jié)點(diǎn)雖然能夠知道自己在進(jìn)行事務(wù)操作過程中的結(jié)果是成功或失敗,但卻無法直接獲取到其他分布式節(jié)點(diǎn)的操作結(jié)果。因此,當(dāng)一個(gè)事務(wù)操作需要跨越多個(gè)分布式節(jié)點(diǎn)的時(shí)候,為了保持事務(wù)處理的ACID特性,需要引入一個(gè)“協(xié)調(diào)者(Coordinator)”的組件來統(tǒng)一調(diào)度所有分布式節(jié)點(diǎn)的執(zhí)行邏輯,這些被調(diào)度的分布式節(jié)點(diǎn)被稱為“參與者”。
一、2PC
2PC,二階段提交協(xié)議,即將事務(wù)的提交過程分為兩個(gè)階段來進(jìn)行處理:準(zhǔn)備階段和提交階段。事務(wù)的發(fā)起者稱協(xié)調(diào)者,事務(wù)的執(zhí)行者稱參與者。
階段1:準(zhǔn)備階段
1、協(xié)調(diào)者向所有參與者發(fā)送事務(wù)內(nèi)容,詢問是否可以提交事務(wù),并等待所有參與者答復(fù)。
2、各參與者執(zhí)行事務(wù)操作,將Undo和Redo信息記入事務(wù)日志中(但不提交事務(wù))。
3、如參與者執(zhí)行成功,給協(xié)調(diào)者反饋YES,即可以提交;如執(zhí)行失敗,給協(xié)調(diào)者反饋NO,即不可提交。
階段2:提交階段
此階段分兩種情況:所有參與者均反饋YES、或任何一個(gè)參與者反饋NO。
①所有參與者均反饋YES時(shí),即提交事務(wù)。
②任何一個(gè)參與者反饋NO時(shí),即中斷事務(wù)。
提交事務(wù):(所有參與者均反饋YES)
1、協(xié)調(diào)者向所有參與者發(fā)出正式提交事務(wù)的請(qǐng)求(即Commit請(qǐng)求)。
2、參與者執(zhí)行Commit請(qǐng)求,并釋放整個(gè)事務(wù)期間占用的資源。
3、各參與者向協(xié)調(diào)者反饋Ack完成的消息。
4、協(xié)調(diào)者收到所有參與者反饋的Ack消息后,即完成事務(wù)提交。
中斷事務(wù):(任何一個(gè)參與者反饋NO)
1、協(xié)調(diào)者向所有參與者發(fā)出回滾請(qǐng)求(即Rollback請(qǐng)求)。
2、參與者使用階段1中的Undo信息執(zhí)行回滾操作,并釋放整個(gè)事務(wù)期間占用的資源。
3、各參與者向協(xié)調(diào)者反饋Ack完成的消息。
4、協(xié)調(diào)者收到所有參與者反饋的Ack消息后,即完成事務(wù)中斷。
2-PC 示意圖如下:

2PC的缺陷
1、同步阻塞:最大的問題即同步阻塞,即:所有參與事務(wù)的邏輯均處于阻塞狀態(tài)。
2、單點(diǎn):協(xié)調(diào)者存在單點(diǎn)問題,如果協(xié)調(diào)者出現(xiàn)故障,參與者將一直處于鎖定狀態(tài)。
3、腦裂:在階段2中,如果只有部分參與者接收并執(zhí)行了Commit請(qǐng)求,會(huì)導(dǎo)致節(jié)點(diǎn)數(shù)據(jù)不一致。
由于2PC存在如上同步阻塞、單點(diǎn)、腦裂問題,因此又出現(xiàn)了2PC的改進(jìn)方案,即3PC。
二、 3-PC
3PC,三階段提交協(xié)議,是2PC的改進(jìn)版本,即將事務(wù)的提交過程分為CanCommit、PreCommit、do Commit三個(gè)階段來進(jìn)行處理。
階段1:CanCommit
1、協(xié)調(diào)者向所有參與者發(fā)出包含事務(wù)內(nèi)容的CanCommit請(qǐng)求,詢問是否可以提交事務(wù),并等待所有參與者響應(yīng)。
2、參與者收到CanCommit請(qǐng)求后,如果認(rèn)為可以執(zhí)行事務(wù)操作,則反饋YES并進(jìn)入預(yù)備狀態(tài),否則反饋NO。
階段2:PreCommit
此階段分兩種情況:
1、所有參與者均反饋YES,即執(zhí)行事務(wù)預(yù)提交。
2、任何一個(gè)參與者反饋NO,或者等待超時(shí)后協(xié)調(diào)者尚無法收到所有參與者的反饋,即中斷事務(wù)。
事務(wù)預(yù)提交:(所有參與者均反饋YES時(shí))
1、協(xié)調(diào)者向所有參與者發(fā)出PreCommit請(qǐng)求,進(jìn)入準(zhǔn)備階段。
2、參與者收到PreCommit請(qǐng)求后,執(zhí)行事務(wù)操作,將Undo和Redo信息記入事務(wù)日志中(但不提交事務(wù))。
3、各參與者向協(xié)調(diào)者反饋Ack響應(yīng)或No響應(yīng),并等待最終指令(提交或終止)。
中斷事務(wù):(任何一個(gè)參與者反饋NO,或者等待超時(shí)后協(xié)調(diào)者尚無法收到所有參與者的反饋時(shí))
1、協(xié)調(diào)者向所有參與者發(fā)出abort請(qǐng)求。
2、無論收到協(xié)調(diào)者發(fā)出的abort請(qǐng)求,或者在等待協(xié)調(diào)者請(qǐng)求過程中出現(xiàn)超時(shí),參與者均會(huì)中斷事務(wù)。
階段3:do Commit
此階段也存在兩種情況:
1、所有參與者均反饋Ack響應(yīng),即執(zhí)行真正的事務(wù)提交。
2、任何一個(gè)參與者反饋NO,或者等待超時(shí)后協(xié)調(diào)者尚無法收到所有參與者的反饋,即中斷事務(wù)。
提交事務(wù):(所有參與者均反饋Ack響應(yīng)時(shí))
1、如果協(xié)調(diào)者處于工作狀態(tài),則向所有參與者發(fā)出do Commit請(qǐng)求。
2、參與者收到do Commit請(qǐng)求后,會(huì)正式執(zhí)行事務(wù)提交,并釋放整個(gè)事務(wù)期間占用的資源。
3、各參與者向協(xié)調(diào)者反饋Ack完成的消息。
4、協(xié)調(diào)者收到所有參與者反饋的Ack消息后,即完成事務(wù)提交。
中斷事務(wù):(任何一個(gè)參與者反饋NO,或者等待超時(shí)后協(xié)調(diào)者尚無法收到所有參與者的反饋時(shí))
1、如果協(xié)調(diào)者處于工作狀態(tài),向所有參與者發(fā)出abort請(qǐng)求。
2、參與者使用階段1中的Undo信息執(zhí)行回滾操作,并釋放整個(gè)事務(wù)期間占用的資源。
3、各參與者向協(xié)調(diào)者反饋Ack完成的消息。
4、協(xié)調(diào)者收到所有參與者反饋的Ack消息后,即完成事務(wù)中斷。
注意:進(jìn)入階段三后,無論協(xié)調(diào)者出現(xiàn)問題,或者協(xié)調(diào)者與參與者網(wǎng)絡(luò)出現(xiàn)問題,都會(huì)導(dǎo)致參與者無法接收到協(xié)調(diào)者發(fā)出的do Commit請(qǐng)求或abort請(qǐng)求。此時(shí),參與者都會(huì)在等待超時(shí)之后,繼續(xù)執(zhí)行事務(wù)提交。
過程如下圖:

3PC的優(yōu)點(diǎn)和缺陷
優(yōu)點(diǎn):降低了阻塞范圍,在等待超時(shí)后協(xié)調(diào)者或參與者會(huì)中斷事務(wù)。避免了協(xié)調(diào)者單點(diǎn)問題,階段3中協(xié)調(diào)者出現(xiàn)問題時(shí),參與者會(huì)繼續(xù)提交事務(wù)。
缺陷:腦裂問題依然存在,即在參與者收到PreCommit請(qǐng)求后等待最終指令,如果此時(shí)協(xié)調(diào)者無法與參與者正常通信,會(huì)導(dǎo)致參與者繼續(xù)提交事務(wù),造成數(shù)據(jù)不一致。
無論2PC或3PC,均無法徹底解決分布式一致性問題。
解決一致性問題,則有Paxos算法,是目前公認(rèn)的解決分布式一致性問題的最有效的算法之一。
參考資料:
從Paxos到Zookeeper 分布式一致性原理與實(shí)踐 [倪超著]
分布式一致性算法2PC和3PC