架构杂谈《四》
分布式一致性協(xié)議
一、引言
在分布式系統(tǒng)中,為了保證數(shù)據(jù)的高可用,通常會將數(shù)據(jù)保留多個副本(replica),這些個副本會放在不同的物理機(jī)上,為了對用戶提供正確的數(shù)據(jù),我們需要保證這些放在不同物理機(jī)上的副本是一致的。為了解決這種分布式一致性問題,提出了很多經(jīng)典的協(xié)議和算法,比較著名的是 兩階段提交協(xié)議和三階段提交協(xié)議。
二、兩階段提交協(xié)議
兩階段提交協(xié)議把分布式事務(wù)分為兩個階段,一個是準(zhǔn)備階段,一個是提交階段。準(zhǔn)備階段和提交階段都是由事務(wù)管理器發(fā)起的,兩階段提交協(xié)議的流程如下:
1、準(zhǔn)備階段:事務(wù)管理器向資源管理器發(fā)起指令,資源管理器評估自己的狀態(tài),如果資源管理器評估指令可以完成。則會寫redo或者undo日志,然后鎖定資源,執(zhí)行操作,但是并不會提交
2、提交階段:如果每個資源管理器明確返回準(zhǔn)備成功,事務(wù)管理器向資源管理器發(fā)起提交指令,資源管理器提交資源變更的事務(wù),釋放鎖定的資源;如果任何一個資源管理明確返回準(zhǔn)備失敗,則事務(wù)管理器向資源管理器發(fā)起中止指令,資源管理器取消已經(jīng)變更的事務(wù),執(zhí)行undo日志。釋放鎖定的資源。
(兩階段提交協(xié)議的成功場景圖)
我們從上圖中可以看到,兩階段提交協(xié)議在準(zhǔn)備階段鎖定資源,這是一個重量級的操作,能保證強(qiáng)一致性,但是實(shí)現(xiàn)起來復(fù)雜、成本大、不夠靈活。還有以下缺點(diǎn):
? (1)、阻塞:對于任何一次指令都必須收到明確的響應(yīng),才會繼續(xù)進(jìn)行下一步,否則處于阻塞狀態(tài),占用的資源一直被鎖定,不會釋放
? (2)、單點(diǎn)故障:如果事務(wù)管理器(協(xié)調(diào)者)掛了(宕機(jī)),資源管理器(參與者)沒有事務(wù)管理器(協(xié)調(diào)者)指揮,則會一直阻塞,盡管可以通過選舉新的協(xié)調(diào)者替代原有的協(xié)調(diào)者,但是參與者接收后也宕機(jī),則新上任的協(xié)調(diào)者無法處理這種情況
? (3)、腦裂:協(xié)調(diào)者發(fā)送提交指令,有的參與者接收到并執(zhí)行了事務(wù),有的參與者沒有接收到事務(wù)就沒有執(zhí)行事務(wù),多個參與者之間是不一致的。
上面的問題雖然很少發(fā)生,但每次發(fā)生都需要人工參與,沒有自動化解決方案,因此兩階段提交協(xié)議在正常情況下能保證系統(tǒng)的強(qiáng)一致性,但在出現(xiàn)異常的情況下,需要人工干預(yù)解決,因此可用性不夠好,其實(shí)這也符合CAP協(xié)議的一致性和可用性不能兼得的原理。
三、三階段提交協(xié)議
三階段提交協(xié)議是兩階段提交協(xié)議的改進(jìn)版本,它通過超時機(jī)制解決了阻塞的問題,并且把兩個階段增加為三個階段。
1、詢問階段:事務(wù)管理器(協(xié)調(diào)者)詢問參與者(資源管理器)是否可以完成指令,參與者只需要回答是或者否,而不需要做真正的操作,這個階段超時會導(dǎo)致中止。
2、準(zhǔn)備階段:如果在詢問階段所有參與者都返回可以執(zhí)行操作,則協(xié)調(diào)者向參與者發(fā)送預(yù)執(zhí)行請求,然后參與者寫 redo 和 undo 日志,執(zhí)行操作但不提交操作;如果在詢問階段任何一個參與者返回不能執(zhí)行操作的結(jié)果,則協(xié)調(diào)者向參與者發(fā)送中止請求,這里的邏輯和兩階段提交協(xié)議的準(zhǔn)備階段是相似的。
3、提交階段:如果每個參與者在準(zhǔn)備階段返回準(zhǔn)備成功,則協(xié)調(diào)者向參與者發(fā)送提交指令,參與者提交資源變更的事務(wù),釋放鎖定的資源;如果任何一個參與者返回準(zhǔn)備失敗,則協(xié)調(diào)者向參與者發(fā)送中止指令,參與者自己取消已經(jīng)變更的事務(wù),執(zhí)行 undo 日志,釋放鎖定的資源。這里的邏輯和兩階段提交協(xié)議的提交階段一致。
(三階段提交協(xié)議的成功場景圖)
三階段提交協(xié)議與兩階段提交協(xié)議主要有以下不同點(diǎn):
(1)、增加了一個詢問階段,詢問階段可以確保盡可能早地發(fā)現(xiàn)無法執(zhí)行操作而需要中止的行為,但是它并不能發(fā)現(xiàn)所有的這種行為,只會減少這種情況的發(fā)生。
(2)、在準(zhǔn)備階段以后,協(xié)調(diào)者和參與者執(zhí)行的任務(wù)中都增加了超時,一旦超時,則協(xié)調(diào)者和參與者都會繼續(xù)提交事務(wù),默認(rèn)為成功。
三階段提交協(xié)議與兩階段提交協(xié)議相比,具有以上的優(yōu)點(diǎn),但是一旦發(fā)生超時,系統(tǒng)仍然會發(fā)生不一致,只不過這種情況很少見。好處是不會阻塞和永遠(yuǎn)鎖定資源?! ?/p>
四、TCC
兩階段和三階段提交協(xié)議,在遇到極端情況時,系統(tǒng)會產(chǎn)生阻塞或者不一致的問題,需要人干預(yù)解決。兩階段及三階段方案中都包含多個參與者、多個階段實(shí)現(xiàn)一個事務(wù)。實(shí)現(xiàn)事務(wù),性能也是一個很大的問題。因此在互聯(lián)網(wǎng)的高并發(fā)系統(tǒng)中,很少有使用兩階段提交和三階段提交協(xié)議的場景。
后來有人提出了TCC協(xié)議,TCC協(xié)議將一個任務(wù)分成 Try、Confirm、Cancel 三個步驟。正常的流程會先執(zhí)行 Try,如果執(zhí)行沒有問題,則再執(zhí)行 Confirm,如果執(zhí)行過程中出現(xiàn)了異常。則執(zhí)行操作的逆操作 Cancel。從正常的流程上講。這還是一個兩階段提交協(xié)議,但在執(zhí)行出現(xiàn)異常后有一定的自我修復(fù)能力,如果任何參與者出現(xiàn)了問題,則協(xié)調(diào)者通過執(zhí)行操作的逆操作來 Cancel 之前的操作。達(dá)到最終一致性狀態(tài)。
可以看出,從時序上講,如果遇到機(jī)端情況,則TCC會有很多問題,如:如果在取消時一些參與者收到指令,而另一些參與者沒有收到指令,則整個系統(tǒng)任然是不一致的,對于這種復(fù)雜的情況,系統(tǒng)首先會通過補(bǔ)償?shù)姆绞絿L試自我修復(fù),如果系統(tǒng)無法修復(fù)。還是需要人工干預(yù)解決。
從 TCC 的邏輯上來看,它是簡化版的三階段提交協(xié)議,解決了兩階段提交協(xié)議的阻塞問題,但還是沒有解決極端情況下出現(xiàn)的問題(不一致和腦裂問題)。然而,TCC 通過自動化補(bǔ)償手段,將需要人工處理的不一致問題降到最低,也是一種很有用的解決方案。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
(TCC 協(xié)議的使用場景)
說明:
1、參考書籍:《分布式服務(wù)架構(gòu):原理、設(shè)計與實(shí)戰(zhàn)》
2、如有不合適的地方請反饋。綜合后更改。
總結(jié)
- 上一篇: 使用kubectl管理k8s集群(三十)
- 下一篇: 译 | 宣布ML.NET 1.2 及模型