分布式事務(wù)常見實(shí)現(xiàn)算法,你知道幾個(gè)?
布式事務(wù)處理算法是確保分布式架構(gòu)下跨多個(gè)節(jié)點(diǎn)或服務(wù)的事務(wù)保持原子性和一致性的技術(shù)特性。本文介紹一些常見的分布式事務(wù)算法,包括2PC/3PC、TCC和Saga、CAP和BASE基本理論,以加深了解。
1、2PC
二階段提交2PC是一致性協(xié)議算法,可以保證數(shù)據(jù)的強(qiáng)一致性,該算法能夠解決很多臨時(shí)性系統(tǒng)故障(包括進(jìn)程、網(wǎng)絡(luò)節(jié)點(diǎn)、通信等故障),被廣泛地使用于關(guān)系型數(shù)據(jù)庫系統(tǒng)中。
1.1 二階段提交過程
2PC協(xié)議中系統(tǒng)分為協(xié)調(diào)者和參與者,整個(gè)過程分為兩個(gè)階段:
1) 階段1:Prepare請(qǐng)求階段
- 在請(qǐng)求階段,協(xié)調(diào)者向事務(wù)的參與者發(fā)起執(zhí)行操作的CanCommit請(qǐng)求,通知事務(wù)參與者準(zhǔn)備提交或取消事務(wù),并等待參與者的響應(yīng);
- 參與者接到請(qǐng)求后,執(zhí)行請(qǐng)求中的事務(wù)操作,記錄undo/redo日志信息,同時(shí)鎖定當(dāng)前記錄
- 參與者反饋事務(wù)的執(zhí)行結(jié)果,如果執(zhí)行成功則返回YES,如果執(zhí)行失敗則返回NO
- 當(dāng)所有的參與者返回操作結(jié)果后,系統(tǒng)進(jìn)入提交階段
2) 階段2:Commit提交階段
- 協(xié)調(diào)者會(huì)根據(jù)所有參與者返回的信息向參與者發(fā)送DoCommit或DoAbort指令
- 當(dāng)且僅當(dāng)所有的參與者返回YES時(shí)協(xié)調(diào)者向所有的參與者發(fā)送DoCommit消息提交事務(wù),否則協(xié)調(diào)者將向所有的參與者發(fā)送DoAbort取消事務(wù)。此時(shí)發(fā)送“Yes”的參與者則會(huì)根據(jù)回滾日志對(duì)之前操作進(jìn)行回滾
- 參與者在接收到協(xié)調(diào)者發(fā)來的消息后向協(xié)調(diào)者發(fā)送“HaveCommitted”消息
- 協(xié)調(diào)者接收到“HaveCommitted”消息,就意味著整個(gè)事務(wù)結(jié)束
1.2 2PC缺點(diǎn)
2PC協(xié)議的優(yōu)點(diǎn)是原理簡(jiǎn)單、實(shí)現(xiàn)方便,但也有以下缺點(diǎn):
- 同步阻塞:在二階段提交的執(zhí)行過程中,所有參與該事務(wù)操作的邏輯都處于阻塞狀態(tài),也就是說,各個(gè)參與者在等待其他參與者響應(yīng)的過程中,將無法進(jìn)行其他任何操作。
- 單點(diǎn)問題:協(xié)調(diào)者的角色在整個(gè)二階段提交協(xié)議中起到了非常重要的作用。一旦協(xié)調(diào)者出現(xiàn)問題,那么整個(gè)二階段提交流程將無法運(yùn)轉(zhuǎn),更為嚴(yán)重的是,如果協(xié)調(diào)者是在階段二中出現(xiàn)問題的話,那么其他參與者將會(huì)一直處于鎖定事務(wù)資源的狀態(tài)中,而無法繼續(xù)完成事務(wù)操作。
- 數(shù)據(jù)不一致:在階段二時(shí),當(dāng)協(xié)調(diào)者向所有的參與者發(fā)送Commit請(qǐng)求之后,發(fā)生了局部網(wǎng)絡(luò)異?;蛘呤菂f(xié)調(diào)者尚未發(fā)送完Commit請(qǐng)求之前自身發(fā)生了崩潰,導(dǎo)致最終只有部分參與者收到了Commit請(qǐng)求。于是,這部分收到了Commit請(qǐng)求的參與者就會(huì)進(jìn)行事務(wù)的提交,而其他沒有收到Commit請(qǐng)求的參與者則無法進(jìn)行事務(wù)提交,于是整個(gè)分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)不一致現(xiàn)象。
- 二階段無法解決的問題:協(xié)調(diào)者在發(fā)出DoCommit消息之后宕機(jī),而唯一接收到這條消息的參與者同時(shí)也宕機(jī)了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者,這條事務(wù)的狀態(tài)也是不確定的,沒人知道事務(wù)是否被已經(jīng)提交。
2、3PC
為了解決2PC過程中同步阻塞和數(shù)據(jù)不一致的問題,3PC協(xié)議在協(xié)調(diào)者和參與者中都引入超時(shí)機(jī)制,并且把兩階段提交協(xié)議的第一個(gè)階段拆分成了兩步:詢問,然后再鎖資源,最后真正提交,包括CanCommit、PreCommit和doCommit三個(gè)階段。
2.1 3PC提交過程

1)CanCommit階段3PC的CanCommit階段和2PC的準(zhǔn)備階段很像。協(xié)調(diào)者向參與者發(fā)送commit請(qǐng)求,參與者如果可以提交就返回Yes響應(yīng),否則返回No響應(yīng)。
2)PreCommit階段
協(xié)調(diào)者根據(jù)參與者的反應(yīng)情況來決定是否可以繼續(xù)事務(wù)的PreCommit操作。根據(jù)響應(yīng)情況,有以下兩種可能。
- 假如協(xié)調(diào)者從所有的參與者獲得的反饋都是Yes響應(yīng),那么就會(huì)進(jìn)行事務(wù)的預(yù)執(zhí)行:
發(fā)送預(yù)提交請(qǐng)求。協(xié)調(diào)者向參與者發(fā)送PreCommit請(qǐng)求,并進(jìn)入Prepared階段。
事務(wù)預(yù)提交。參與者接收到PreCommit請(qǐng)求后,會(huì)執(zhí)行事務(wù)操作,并將undo和redo信息記錄到事務(wù)日志中。
響應(yīng)反饋。如果參與者成功的執(zhí)行了事務(wù)操作,則返回ACK響應(yīng),同時(shí)開始等待最終指令。
- 假如有任何一個(gè)參與者向協(xié)調(diào)者發(fā)送了No響應(yīng),或者等待超時(shí)之后,協(xié)調(diào)者都沒有接到參與者的響應(yīng),那么就中斷事務(wù):
- 發(fā)送中斷請(qǐng)求。協(xié)調(diào)者向所有參與者發(fā)送abort請(qǐng)求。
- 中斷事務(wù)。參與者收到來自協(xié)調(diào)者的abort請(qǐng)求之后(或超時(shí)之后,仍未收到Cohort的請(qǐng)求),執(zhí)行事務(wù)的中斷。
3)DoCommit階段
該階段進(jìn)行真正的事務(wù)提交,也可以分為以下兩種情況:
- 執(zhí)行提交
發(fā)送提交請(qǐng)求。協(xié)調(diào)者接收到參與者發(fā)送的ACK響應(yīng),那么他將從預(yù)提交狀態(tài)進(jìn)入到提交狀態(tài)。并向所有參與者發(fā)送doCommit請(qǐng)求。
事務(wù)提交。參與者接收到doCommit請(qǐng)求之后,執(zhí)行正式的事務(wù)提交。并在完成事務(wù)提交之后釋放所有事務(wù)資源。
響應(yīng)反饋。事務(wù)提交完之后,向協(xié)調(diào)者發(fā)送ACK響應(yīng)。
完成事務(wù)。協(xié)調(diào)者接收到所有參與者的ACK響應(yīng)之后,完成事務(wù)。
- 中斷事務(wù)
- 協(xié)調(diào)者沒有接收到參與者發(fā)送的ACK響應(yīng)(可能是接受者發(fā)送的不是ACK響應(yīng),也可能響應(yīng)超時(shí)),那么就會(huì)執(zhí)行中斷事務(wù)。
2.2 3PC優(yōu)缺點(diǎn)
- 三階段優(yōu)點(diǎn):
降低了二階段的同步阻塞范圍(在第二階段,只要參與者收到preCommit請(qǐng)求,就會(huì)執(zhí)行事務(wù),此后,不管能不能收到協(xié)調(diào)者的doCommit請(qǐng)求,都會(huì)執(zhí)行事務(wù)提交,不會(huì)出現(xiàn)阻塞問題)
解決單點(diǎn)問題:進(jìn)入階段三會(huì)出現(xiàn)兩種情況: 1:協(xié)調(diào)者出現(xiàn)問題; 2:協(xié)調(diào)者與參與者之間出現(xiàn)網(wǎng)絡(luò)故障; 都導(dǎo)致參與者無法收到doCommit請(qǐng)求,但參與者在超時(shí)之后都會(huì)提交事務(wù)
- 三階段缺點(diǎn):
- 數(shù)據(jù)不一致:參與者收到preCommit請(qǐng)求,此時(shí)如果出現(xiàn)網(wǎng)絡(luò)分區(qū),協(xié)調(diào)者與參與者之間無法進(jìn)行正常網(wǎng)絡(luò)通信,參與者在超時(shí)之后還是會(huì)進(jìn)行事務(wù)提交,就會(huì)出現(xiàn)數(shù)據(jù)不一致。
3、Saga模式
Saga模式屬于長(zhǎng)事務(wù)解決方案,其核心思想把一個(gè)分布式事務(wù)拆分為多個(gè)本地事務(wù),每個(gè)本地事務(wù)都有相應(yīng)的執(zhí)行模塊和補(bǔ)償模塊,當(dāng)Saga事務(wù)中任意一個(gè)本地事務(wù)出錯(cuò)時(shí),可以通過調(diào)用相關(guān)的補(bǔ)償方法恢復(fù)之前的事務(wù),達(dá)到事務(wù)最終一致性。Saga模式由三部分組成:
- LLT(Long Live Transaction):由一個(gè)個(gè)本地事務(wù)組成的事務(wù)鏈。
- 本地事務(wù):事務(wù)鏈由一個(gè)個(gè)子事務(wù)(本地事務(wù))組成,LLT = T1+T2+T3+…+Ti。
- 補(bǔ)償:每個(gè)本地事務(wù) Ti 有對(duì)應(yīng)的補(bǔ)償 Ci。
在業(yè)務(wù)流程中,正常情況下每個(gè)參與者都在一階段提交本地事務(wù),按照T1->T2->T3->…->Ti的順序執(zhí)行。當(dāng)出現(xiàn)異常時(shí),則會(huì)發(fā)起補(bǔ)償,將之前提交的事務(wù)回滾,執(zhí)行順序變成T1->T2->T3->C3->C2->C1。如下圖所示:

Saga模式的恢復(fù)其實(shí)有兩種:向后恢復(fù)(Backward Recovery)和向前恢復(fù)(Forward Recovery)
- 向后恢復(fù)(Backward Recovery):撤銷掉之前所有成功子事務(wù)。如果任意本地子事務(wù)失敗,則補(bǔ)償已完成的事務(wù)。如異常情況的執(zhí)行順序T1,T2,T3,…Ti,Ci,…C3,C2,C1。
- 向前恢復(fù)(Forward Recovery):即重試失敗的事務(wù),適用于必須要成功的場(chǎng)景,該情況下不需要Ci。執(zhí)行順序:T1,T2,…,Tj(失?。?Tj(重試),…,Ti。
Saga模式滿足事務(wù)的ACD三個(gè)特性:
- 原子性:Saga協(xié)調(diào)器協(xié)調(diào)事務(wù)鏈中的本地事務(wù)要么全部提交,要么全部回滾
- 一致性:Saga事務(wù)可以實(shí)現(xiàn)最終一致性
- 持久性:基于本地事務(wù),所以這個(gè)特性可以很好實(shí)現(xiàn)
但是缺乏隔離性會(huì)引發(fā)臟讀、幻讀和不可重復(fù)讀等問題,因此需要在業(yè)務(wù)設(shè)計(jì)上去解決這個(gè)問題,通常在應(yīng)用層面通過邏輯鎖或者串行化操作來確保讀取數(shù)據(jù)的準(zhǔn)確性。
實(shí)現(xiàn)Saga的注意事項(xiàng):
(1) Ti和Ci必須是冪等的。如向后恢復(fù)和向前恢復(fù)時(shí)候如果不是冪等操作會(huì)導(dǎo)致數(shù)據(jù)不一致。
(2) Ci必須是能夠成功的,如果無法成功則需要人工介入。
(3) Ti->Ci和Ci->Ti的執(zhí)行結(jié)果必須是一樣的。4、TCC模式
TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年發(fā)表的論文《Life beyond Distributed Transactions:an Apostate’s Opinion》中提出。TCC采用補(bǔ)償機(jī)制,其核心思想是針對(duì)每個(gè)操作,都要注冊(cè)一個(gè)與其對(duì)應(yīng)的確認(rèn)和補(bǔ)償,通過對(duì)資源的預(yù)留盡早釋放對(duì)資源的加鎖,提交則完成資源的確認(rèn),回滾則釋放預(yù)留資源。TCC要求應(yīng)用的每個(gè)服務(wù)提供 try、confirm、cancel三個(gè)接口,這些完全由業(yè)務(wù)實(shí)現(xiàn),對(duì)業(yè)務(wù)侵入較大。
- Try階段:嘗試執(zhí)行,完成所有業(yè)務(wù)檢查(一致性), 預(yù)留必須業(yè)務(wù)資源(準(zhǔn)隔離性)
- Confirm階段:確認(rèn)執(zhí)行業(yè)務(wù),不作任何業(yè)務(wù)檢查,只使用Try階段預(yù)留的業(yè)務(wù)資源Confirm操作要求具備冪等設(shè)計(jì),Confirm失敗后需要進(jìn)行重試。
- Cancel階段:取消執(zhí)行,釋放Try階段預(yù)留的業(yè)務(wù)資源。Cancel階段的異常和Confirm階段異常處理方案基本上一致,要求滿足冪等設(shè)計(jì)。

TCC模式處理流程如上圖所示,包括三部分:
- 主業(yè)務(wù)程序:負(fù)責(zé)發(fā)起并完成整個(gè)業(yè)務(wù)活動(dòng),在圖中由它向TM注冊(cè)TCC事務(wù)并開啟分布式事務(wù),執(zhí)行業(yè)務(wù)
- 分支服務(wù):整個(gè)業(yè)務(wù)活動(dòng)的參與方,實(shí)現(xiàn)Try、Confirm和Cancel動(dòng)作,供主業(yè)務(wù)程序調(diào)用。對(duì)應(yīng)圖中的微服務(wù)A和微服務(wù)B,執(zhí)行Try執(zhí)行,并根據(jù)TM返回的結(jié)果執(zhí)行Confirm或Cancel
- 事務(wù)管理器:管理整個(gè)業(yè)務(wù)活動(dòng),包括記錄事務(wù)狀態(tài),調(diào)用分支服務(wù)的Confirm/Cancel 操作
TCC模式相較于Saga模式來說應(yīng)用可以自定義數(shù)據(jù)操作的粒度,降低了鎖沖突,提升業(yè)務(wù)并發(fā)度;但是對(duì)應(yīng)用侵入較強(qiáng),開發(fā)量較大,需要提供Try/Confirm/Cancel接口。
5、不同分布式事務(wù)算法對(duì)比
上述四種分布式事務(wù)的方案,在事務(wù)一致性、實(shí)現(xiàn)復(fù)雜性、對(duì)業(yè)務(wù)的侵入性、使用局限性、性能和維護(hù)成本等角度,總結(jié)如下表:
屬性 | 2PC | 3PC | TCC | Saga |
事務(wù)一致性 | 強(qiáng) | 強(qiáng) | 弱 | 弱 |
復(fù)雜性 | 低 | 中 | 中 | 高 |
業(yè)務(wù)侵入性 | 小 | 小 | 小 | 大 |
使用局限性 | 中 | 中 | 中 | 高 |
性能 | 低 | 中 | 高 | 中 |
維護(hù)成本 | 低 | 中 | 中 | 高 |
不同模式有不同的的使用場(chǎng)景,如下所示:
- 2PC/3PC:依賴于數(shù)據(jù)庫,能夠很好的提供強(qiáng)一致性和強(qiáng)事務(wù)性,但延遲比較高,比較適合傳統(tǒng)的單體應(yīng)用,在同一個(gè)方法中存在跨庫操作的情況,不適合高并發(fā)和高性能要求的場(chǎng)景
- Saga模式:由于Saga事務(wù)不能保證隔離性,需要在業(yè)務(wù)層控制并發(fā),適合于業(yè)務(wù)場(chǎng)景事務(wù)并發(fā)操作同一資源較少的情況。Saga由于缺少預(yù)提交動(dòng)作,導(dǎo)致補(bǔ)償動(dòng)作的實(shí)現(xiàn)比較麻煩,例如業(yè)務(wù)是發(fā)送短信,補(bǔ)償動(dòng)作則得再發(fā)送一次短信說明撤銷,用戶體驗(yàn)比較差。所以,Saga事務(wù)較適用于補(bǔ)償動(dòng)作容易處理的場(chǎng)景。
- TCC:適用于執(zhí)行時(shí)間確定且較短,實(shí)時(shí)性要求高,對(duì)數(shù)據(jù)一致性要求高,比如金融類交易和支付類業(yè)務(wù)
6、CAP理論
CAP理論是計(jì)算機(jī)科學(xué)家Eric Brewer在2000年提出的理論猜想,在2002年被證明并成為分布式計(jì)算領(lǐng)域公認(rèn)的定理,其理論的基本觀念是,在分布式系統(tǒng)中不可能同時(shí)滿足以下三個(gè)特性:
- C:consistency一致性,指系統(tǒng)在執(zhí)行某些操作后仍處于一致狀態(tài);
- A:Availability可用性,指所有的操作在合理的時(shí)間內(nèi)都得到響應(yīng);
- P:Partition Tolerance分區(qū)容錯(cuò)性,指在網(wǎng)絡(luò)分區(qū)故障時(shí),系統(tǒng)仍能繼續(xù)提供服務(wù)。
6.1 Consistency一致性
CAP理論中的一致性指的是Serializability可線性化的意思,也就是非常特殊的強(qiáng)一致性,但是這里的Consistency和ACID中的一致性是兩回事,事務(wù)中的一致性包含了對(duì)狀態(tài)的后續(xù)處理而CAP定理并不涉及到狀態(tài)的后續(xù)處理。因此CAP中的一致性指"all nodes see the same data at the same time",即更新操作成功后,所有節(jié)點(diǎn)在同一時(shí)間的數(shù)據(jù)完全一致。對(duì)于一致性的理解,可以從客戶端和服務(wù)端兩個(gè)不同的視角來分析。
- 從客戶端來看,一致性主要指的是多并發(fā)請(qǐng)求時(shí)更新過的數(shù)據(jù)如何獲取的問題。如果更新過的數(shù)據(jù)需要立刻被后續(xù)的請(qǐng)求獲取到就是強(qiáng)一致性,如果能容忍后續(xù)的請(qǐng)求部分或者全部訪問不到則是弱一致性,如果經(jīng)過一段時(shí)間后要求能訪問到更新后的數(shù)據(jù)則是最終一致性。
- 從服務(wù)端來看,一致性則是數(shù)據(jù)更新后如何同步到整個(gè)分布式系統(tǒng),以保證數(shù)據(jù)最終一致性。
一致性一般在并發(fā)讀寫的時(shí)候才出現(xiàn)這個(gè)問題,需要結(jié)合并發(fā)讀寫的場(chǎng)景考慮

- 如上左圖所示,客戶端向節(jié)點(diǎn)N1更新數(shù)據(jù)V0->V1,在接下來讀操作過程中,從N1節(jié)點(diǎn)讀取的是V1,N2節(jié)點(diǎn)讀取的是V0,對(duì)于單節(jié)點(diǎn)沒有問題,但是在分布式系統(tǒng)中N1節(jié)點(diǎn)和N2節(jié)點(diǎn)讀取的結(jié)果就不一致了
- 如上右圖所示,客戶端在向N1發(fā)起寫操作時(shí),N1節(jié)點(diǎn)向N2節(jié)點(diǎn)發(fā)起了同步操作,將兩個(gè)節(jié)點(diǎn)的值都修改為V1,這時(shí)客戶端從N1和N2節(jié)點(diǎn)獲取到的值都是V1,保證了一致性
上述例子用可線性化解釋就是
如果B操作在成功完成A操作之后,那么整個(gè)系統(tǒng)對(duì)B操作來說必須表現(xiàn)為A操作已經(jīng)完成了或者更新的狀態(tài)。
如果系統(tǒng)內(nèi)部發(fā)生了故障從而導(dǎo)致系統(tǒng)的節(jié)點(diǎn)無法發(fā)生一致性變化,比如N2節(jié)點(diǎn)無法同步N1節(jié)點(diǎn)的數(shù)據(jù)。這也意味著客戶端查詢最新數(shù)據(jù)的時(shí)候,部分節(jié)點(diǎn)很可能會(huì)看到舊數(shù)據(jù),或者說獲取到不同版本的數(shù)據(jù)。此時(shí),為了保證分布式系統(tǒng)對(duì)外的數(shù)據(jù)一致性,于是選擇不返回任何數(shù)據(jù)。
6.2 Availability可用性
可用性指"reads and writes always succeed",即要求系統(tǒng)內(nèi)的節(jié)點(diǎn)們接收到了無論是寫請(qǐng)求還是讀請(qǐng)求,都要能處理并給回響應(yīng)結(jié)果。同時(shí)有幾點(diǎn)必須滿足的條件:
- 返回結(jié)果必須在合理的時(shí)間以內(nèi),這個(gè)合理的時(shí)間是根據(jù)業(yè)務(wù)來定的,如果超過業(yè)務(wù)規(guī)定的返回時(shí)間這個(gè)系統(tǒng)也就不滿足可用性;
- 系統(tǒng)能所有能正常接收請(qǐng)求的節(jié)點(diǎn)都能返回結(jié)果,如果節(jié)點(diǎn)宕機(jī)了不能正常接收請(qǐng)求但是其它節(jié)點(diǎn)可以正常返回,可以說系統(tǒng)依然是可用的,不影響可用性指標(biāo)。如果所有節(jié)點(diǎn)都能返回,但是返回的數(shù)據(jù)不一致,其中一個(gè)節(jié)點(diǎn)是1天前的數(shù)據(jù),另一個(gè)是1s前的,也稱為系統(tǒng)可用的。
一般在描述一個(gè)系統(tǒng)可用性時(shí),通過停機(jī)時(shí)間來計(jì)算,比如某某系統(tǒng)可用性可以達(dá)到5個(gè)9,意思就是說該系統(tǒng)的可用水平是99.999%,即全年停機(jī)時(shí)間不超過(1-0.99999)36524*60 = 5.256min,這是一個(gè)極高的要求。
6.3 Partition tolerance分區(qū)容錯(cuò)性
分布式系統(tǒng)架構(gòu)下會(huì)有多個(gè)節(jié)點(diǎn),這些節(jié)點(diǎn)之間通過網(wǎng)絡(luò)進(jìn)行通信,但是當(dāng)網(wǎng)絡(luò)故障或其它原因節(jié)點(diǎn)之間通信出現(xiàn)異常,當(dāng)前的分布式系統(tǒng)就出現(xiàn)了分區(qū)。分區(qū)容錯(cuò)性指"the system continues to operate despite arbitrary message loss or failure of part of the system",即分布式系統(tǒng)在遇到某節(jié)點(diǎn)或網(wǎng)絡(luò)分區(qū)故障的時(shí)候,仍然能夠?qū)ν馓峁M足一致性和可用性的服務(wù)。
6.4 CAP之間權(quán)衡
根據(jù)CAP理論,在分布式系統(tǒng)中無法同時(shí)滿足一致性、可用性和分區(qū)容錯(cuò)性,在實(shí)際應(yīng)用中又如何來進(jìn)行取舍。
6.4.1 CA模型
舍棄分區(qū)容錯(cuò)性意味著將所有的服務(wù)器搬到一個(gè)網(wǎng)絡(luò)節(jié)點(diǎn)內(nèi),顯然不滿足分布式系統(tǒng)的可伸縮性擴(kuò)展要求。因此在分布式系統(tǒng)中P是一個(gè)基本要求,不選 P,一旦發(fā)生分區(qū)錯(cuò)誤,整個(gè)分布式系統(tǒng)就完全無法使用了,這是不符合實(shí)際需要的。所以,對(duì)于分布式系統(tǒng),我們只能能考慮當(dāng)發(fā)生分區(qū)錯(cuò)誤時(shí),如何選擇一致性和可用性。CA模型常見的例子包括單站點(diǎn)數(shù)據(jù)庫、集群數(shù)據(jù)庫、LDAP和XFS文件系統(tǒng)等,通常是通過兩階段提交和緩存驗(yàn)證協(xié)議實(shí)現(xiàn)的。
6.4.2 CP模型
舍棄A保證Consistency,不同節(jié)點(diǎn)之間需要保證數(shù)據(jù)的一致性,但是因?yàn)榫W(wǎng)絡(luò)分區(qū)的不穩(wěn)定,可能出現(xiàn)其它節(jié)點(diǎn)的數(shù)據(jù)沒有及時(shí)更新。如果一個(gè)分布式系統(tǒng)不要求強(qiáng)的可用性,即允許系統(tǒng)停機(jī)或者長(zhǎng)時(shí)間無響應(yīng)的話,就可以在CAP三者中保障CP而舍棄A。這樣的分布式系統(tǒng)一旦發(fā)生網(wǎng)絡(luò)故障或者消息丟失等情況,就要犧牲用戶體驗(yàn),等數(shù)據(jù)一致后再讓用戶訪問系統(tǒng)。CP模型下典型的場(chǎng)景是分布式數(shù)據(jù)庫,通過悲觀鎖機(jī)制或少數(shù)分區(qū)不可用來優(yōu)先保證數(shù)據(jù)一致性。像分布式緩存Redis、分布式協(xié)調(diào)中心Zookeeper,滿足分布式系統(tǒng)下的數(shù)據(jù)一致性是最基本的要求。
6.4.3 AP模型
AP模型是在保證高可用和分區(qū)容錯(cuò)性的同時(shí),舍棄數(shù)據(jù)一致性。為了保證高可用性,分布式系統(tǒng)下的不同節(jié)點(diǎn)需要立即返回結(jié)果給客戶端,這樣可能會(huì)出現(xiàn)不同節(jié)點(diǎn)之間的數(shù)據(jù)不一致,也就是會(huì)出現(xiàn)全局?jǐn)?shù)據(jù)的不一致。也可以說是舍棄了數(shù)據(jù)的強(qiáng)一致性,保證的是數(shù)據(jù)的最終一致性(BASE理論)。AP模型使用的場(chǎng)景非常多,在一些高并發(fā)的系統(tǒng)中利用排隊(duì)和樂觀鎖機(jī)制優(yōu)先保證系統(tǒng)的可用性,避免造成系統(tǒng)的阻塞。
7、BASE理論
在分布式系統(tǒng)中,面對(duì)CAP權(quán)衡時(shí),通常的做法會(huì)選擇AP舍棄C(舍棄強(qiáng)一致性但保證最終一致性),這其實(shí)也是分布式領(lǐng)域的另外一個(gè)理論,叫BASE理論。BASE是指基本可用(Basically Available)、軟狀態(tài)( Soft State)、最終一致性( Eventual Consistency)。BASE理論是對(duì)CAP理論的延伸,其核心思想是:
即使無法做到強(qiáng)一致性(Strong consistency),但每個(gè)應(yīng)用都可以根據(jù)自身的業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性(Eventual consistency)
7.1 基本可用(Basically Available)
基本可用是指分布式系統(tǒng)在出現(xiàn)故障時(shí),允許損失部分可用性,即保證核心可用。
- 響應(yīng)時(shí)間上的損失:正常情況下的客戶端請(qǐng)求0.5s即返回給用戶結(jié)果,而基本可用的情況下可以在1秒甚至2s返回結(jié)果,超過一定閾值用戶就接受不了
- 功能上的損失:在一個(gè)購物網(wǎng)站上,正常情況下,用戶可以順利完成每一筆訂單,但是到了促銷活動(dòng)期間,為了保障購物系統(tǒng)的穩(wěn)定性,部分消費(fèi)者可能會(huì)被引導(dǎo)到一個(gè)服務(wù)降級(jí)頁面。
7.2 軟狀態(tài)(Soft State)
軟狀態(tài)是相對(duì)原子性來說的
- 原子性(硬狀態(tài)):要求多個(gè)節(jié)點(diǎn)的數(shù)據(jù)副本都是一致的,這是一種"硬狀態(tài)"
- 軟狀態(tài)(弱狀態(tài)):允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認(rèn)為該狀態(tài)不影響系統(tǒng)的整體可用性,即允許系統(tǒng)在多個(gè)不同節(jié)點(diǎn)的數(shù)據(jù)副本存在數(shù)據(jù)延遲
比如在分布式數(shù)據(jù)庫MySQL的復(fù)制中一般一份數(shù)據(jù)會(huì)有多個(gè)副本,允許不同節(jié)點(diǎn)間副本同步的延時(shí)就是軟狀態(tài)的體現(xiàn)。
7.3 最終一致性(Eventual Consistency)
系統(tǒng)不可能一直是軟狀態(tài),必須有個(gè)時(shí)間期限。在期限過后,應(yīng)當(dāng)保證所有副本保持?jǐn)?shù)據(jù)一致性,從而達(dá)到數(shù)據(jù)的最終一致性。這個(gè)時(shí)間期限取決于網(wǎng)絡(luò)延時(shí),系統(tǒng)負(fù)載,數(shù)據(jù)復(fù)制方案設(shè)計(jì)等等因素。最終一致性是弱一致性的特定形式,官方的定義是:
系統(tǒng)能夠保證在沒有其他新的更新操作的情況下,數(shù)據(jù)最終一定能夠達(dá)到一致的狀態(tài),因此所有客戶端對(duì)系統(tǒng)的數(shù)據(jù)訪問最終都能夠獲取到最新的值。


























