分布式事務(wù)CAP兩階段提交及三階段提交詳解
1 關(guān)于分布式系統(tǒng)
1.1 介紹
我們常見的單體結(jié)構(gòu)的集中式系統(tǒng),一般整個(gè)項(xiàng)目就是一個(gè)獨(dú)立的應(yīng)用,所有的模塊都聚合在一起。明顯的弊端就是不易擴(kuò)展、發(fā)布冗重、服務(wù)治理不好做。
所以我們把整個(gè)系統(tǒng)拆分成若干個(gè)具備獨(dú)立運(yùn)行能力的計(jì)算服務(wù)的集合,而從用戶的角度看,是一個(gè)完整的系統(tǒng),但實(shí)際上,它是一個(gè)分布式服務(wù)的集合。
分布式系統(tǒng)主要從以下幾個(gè)方面進(jìn)行裂變:
- 應(yīng)用可以從業(yè)務(wù)領(lǐng)域拆分成多個(gè)module,每個(gè)module還可以再按項(xiàng)目結(jié)構(gòu)分成接口層、業(yè)務(wù)層、數(shù)據(jù)訪問層;當(dāng)然也可以按訪問入口進(jìn)行拆分,如移動(dòng)、桌面、Web端訪問的是不同的類型接口服務(wù);
- 數(shù)據(jù)庫(kù)可以按業(yè)務(wù)類型拆分成多個(gè)實(shí)例,還可以對(duì)單庫(kù)或單表進(jìn)行分庫(kù)分表;參考我的這篇《Mysql數(shù)據(jù)庫(kù)分庫(kù)分表全面瓦解》
- 增加一些中間件,來(lái)保證分布式系統(tǒng)的高可用,如分布式緩存、搜索服務(wù)、文件服務(wù)、消息隊(duì)列、非關(guān)系型數(shù)據(jù)庫(kù)等中間件;
1.2 優(yōu)勢(shì)和不足
分布式系統(tǒng)可以解決集中式不便擴(kuò)展的弊端,提供了便捷的擴(kuò)展性、獨(dú)立的服務(wù)治理,并提高了安全可靠性。隨著微服務(wù)技術(shù)(Spring Cloud、Dubbo) 以及容器技術(shù)(Kubernetes、Docker)的大熱,分布式技術(shù)發(fā)展非常迅速。
不足的地方:分布式系統(tǒng)雖好,也帶來(lái)了系統(tǒng)的復(fù)雜性,如分布式事務(wù)、分布式鎖、分布式session、數(shù)據(jù)一致性等都是現(xiàn)在分布式系統(tǒng)中需要解決的難題,雖然已經(jīng)有很多成熟的方案,但都不完美。
分布式系統(tǒng)的便利,其實(shí)是犧牲了一些開發(fā)、測(cè)試、運(yùn)維 成本的,讓工作量增加了,所以分布式系統(tǒng)管理不好反而會(huì)變成一種負(fù)擔(dān)。
2 分布式事務(wù)
分布式事務(wù)就是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上。
分布式場(chǎng)景下一次完整的操作由不同的action組成,這些actions可能分布在不同的服務(wù)器上,且屬于不同的應(yīng)用,分布式事務(wù)需要保證這些action要么全部成功,要么全部失敗。保證單個(gè)完整操作的原子性。
本質(zhì)上來(lái)說(shuō),分布式事務(wù)就是為了保證不同數(shù)據(jù)庫(kù)的數(shù)據(jù)一致性。
2.1 CAP理論
CAP 定理(也稱為 Brewer 定理),指的是在分布式計(jì)算環(huán)境下,有3個(gè)核心的需求:
1、一致性(Consistency):再分布,所有實(shí)例節(jié)點(diǎn)同一時(shí)間看到是相同的數(shù)據(jù)
2、可用性(Availability):不管是否成功,確保每一個(gè)請(qǐng)求都能接收到響應(yīng)
3、分區(qū)容錯(cuò)性(Partition Tolerance):系統(tǒng)任意分區(qū)后,在網(wǎng)絡(luò)故障時(shí),仍能操作
CAP理論告訴我們,分布式系統(tǒng)不可能同時(shí)滿足以下三種。最多只能同時(shí)滿足其中的兩項(xiàng),因?yàn)楹芏鄷r(shí)候P是必須的, 因此往往選擇就在CP或者AP中
2.2 CAP的組合情況
CA: 放棄分區(qū)容錯(cuò)性。非分布式架構(gòu),比如關(guān)系數(shù)據(jù)庫(kù),因?yàn)闆]有分區(qū),但是在分布式系統(tǒng)下,CA組合就不建議了。
AP: 放棄強(qiáng)一致性。追求最終一致性,類似的場(chǎng)景比如轉(zhuǎn)賬,可以接受兩小時(shí)后到賬,Eureka的注冊(cè)也是類似的做法。
CP: 放棄可用性。zookeeper在leader宕機(jī)后,選舉期間是不提供服務(wù)的。類似的場(chǎng)景比如支付完成之后出訂單,必須一進(jìn)一出都完成才行。
結(jié)論:在分布式系統(tǒng)中AP運(yùn)用的最多,因?yàn)樗艞壍氖菑?qiáng)一致性,追求的是最終一致性,性價(jià)比最高
2.3 數(shù)據(jù)一致性模型
分布式系統(tǒng)通過同步數(shù)據(jù)的副本來(lái)提高系統(tǒng)的可靠性和容錯(cuò)性,而且數(shù)據(jù)的不同的副本,合理會(huì)存在不同的機(jī)器或集群上。
強(qiáng)一致性:當(dāng)用戶的操作完成之后,會(huì)立馬被同步到不同的數(shù)據(jù)副本中,后續(xù)其他任意請(qǐng)求都會(huì)獲得更新過的值。這種對(duì)用戶的可見性是最友好的,能始終保證讀到正確的值。根據(jù) CAP 理論,這種實(shí)現(xiàn)需要犧牲可用性。
弱一致性:系統(tǒng)并不保證所有請(qǐng)求的訪問都會(huì)獲得最新值。數(shù)據(jù)寫入成功之后,不承諾立即可以讀,也不承諾具體多久之后可以讀到,甚至讀不到。在請(qǐng)求獲得數(shù)據(jù)更新的這段時(shí)間,我i們稱之為“不一致性窗口”。
最終一致性:是弱一致性的一種。系統(tǒng)保證在沒有后續(xù)更新的前提下,系統(tǒng)最終返回上一次更新操作的值。在沒有故障發(fā)生的前提下,不一致窗口的時(shí)間主要受通信延遲,系統(tǒng)負(fù)載和復(fù)制副本的個(gè)數(shù)影響。
常見的事務(wù)處理機(jī)制:
1、Master-Slave 復(fù)制:寫請(qǐng)求由 Master 負(fù)責(zé),寫入 Master 后,由 Master 同步到 Slave 上。
異步同步,所以是弱/最終一致性。
2、Master-Master 主主復(fù)制
異步同步,最終的一致性,多個(gè)節(jié)點(diǎn)間需要序列化協(xié)議。
2.4 分布式事務(wù)應(yīng)用場(chǎng)景
2.4.1 典型支付場(chǎng)景
這是最經(jīng)典的場(chǎng)景。支付過程,要先對(duì)買家賬戶進(jìn)行扣款,同時(shí)對(duì)賣家賬戶進(jìn)行付款,
像這類的操作,必須在一個(gè)事務(wù)中執(zhí)行,保證原子性,要么都成功,要么都不成功。但是往往買家的支付平臺(tái)和賣家的支付平臺(tái)不一致,即使都在一個(gè)平臺(tái)下,所屬的業(yè)務(wù)服務(wù)和數(shù)據(jù)服務(wù)
(歸屬不同表甚至不同庫(kù),比如賣家中心庫(kù)、賣家中心庫(kù))也不是同一個(gè)。針對(duì)于不同的業(yè)務(wù)平臺(tái)、不同的數(shù)據(jù)庫(kù)做操作必然要引入分布式事務(wù)。
2.4.2 在線下單
同理,買家在電商平臺(tái)下單,往往會(huì)涉及到兩個(gè)動(dòng)作,一個(gè)是扣庫(kù)存,第二個(gè)是更新訂單狀態(tài),庫(kù)存和訂單一般屬于不同的數(shù)據(jù)庫(kù),需要使用分布式事務(wù)保證數(shù)據(jù)一致性。
2.4.3 跨行轉(zhuǎn)賬
跨行轉(zhuǎn)賬問題也是一個(gè)典型的分布式事務(wù),用戶A同學(xué)向B同學(xué)的賬戶轉(zhuǎn)賬500,要先進(jìn)行A同學(xué)的賬戶-500,然后B同學(xué)的賬戶+500,既然是不同的銀行,
涉及不同的業(yè)務(wù)平臺(tái),為了保證這兩個(gè)操作步驟的一致,分布式事務(wù)必然要被引入。
2.5 常見分布式一致性保障(分布式事務(wù)解決方案)
2.5.1 XA 兩階段提交協(xié)議
兩階段提交協(xié)議(Two-phase commit protocol),簡(jiǎn)稱2PC,過程涉及到協(xié)調(diào)者和參與者。
它是一種強(qiáng)一致性設(shè)計(jì),引入一個(gè)事務(wù)協(xié)調(diào)者的角色來(lái)協(xié)調(diào)管理各參與者的提交和回滾,二階段分別指的是準(zhǔn)備(投票)和提交兩個(gè)階段。
第一階段(準(zhǔn)備階段)
為事務(wù)協(xié)調(diào)者的節(jié)點(diǎn)會(huì)首先向所有的參與者節(jié)點(diǎn)發(fā)送Prepare請(qǐng)求。
在接到Prepare請(qǐng)求之后,每一個(gè)參與者節(jié)點(diǎn)會(huì)各自執(zhí)行與事務(wù)有關(guān)的數(shù)據(jù)更新,寫入U(xiǎn)ndo Log(撤銷)和 Redo Log(重做)。
如果參與者執(zhí)行成功,暫時(shí)不提交事務(wù),而是向事務(wù)協(xié)調(diào)節(jié)點(diǎn)返回“完成”消息。當(dāng)事務(wù)協(xié)調(diào)者接到了所有參與者的返回消息,整個(gè)分布式事務(wù)將會(huì)進(jìn)入第二階段。
假如在第一階段有一個(gè)參與者返回失敗,那么協(xié)調(diào)者就會(huì)向所有參與者發(fā)送回滾事務(wù)的請(qǐng)求,即分布式事務(wù)執(zhí)行失敗。如下圖:
第二階段(提交階段)
如果事務(wù)協(xié)調(diào)節(jié)點(diǎn)在之前所收到都是正向返回,那么它將會(huì)向所有事務(wù)參與者發(fā)出Commit請(qǐng)求。
接到Commit請(qǐng)求之后,事務(wù)參與者節(jié)點(diǎn)會(huì)各自進(jìn)行本地的事務(wù)提交,并釋放鎖資源。當(dāng)本地事務(wù)完成提交后,將會(huì)向事務(wù)協(xié)調(diào)者返回“完成”消息。
當(dāng)事務(wù)協(xié)調(diào)者接收到所有事務(wù)參與者的“完成”反饋,整個(gè)分布式事務(wù)完成。
當(dāng)有一個(gè)Commit 不成功,那其他的應(yīng)該也是提交不成功的。
2.5.2 XA三階段提交
三階段提交:CanCommit 階段、PreCommit 階段、DoCommit 階段,簡(jiǎn)稱3PC
三階段提交協(xié)議(Three-phase commit protocol,3PC),是二階段提交(2PC)的改進(jìn)版本。與兩階段提交不同的是,三階段提交有兩個(gè)改動(dòng)點(diǎn):
引入超時(shí)機(jī)制。同時(shí)在協(xié)調(diào)者和參與者中都引入超時(shí)機(jī)制。
在第一階段和第二階段中插入一個(gè)準(zhǔn)備階段。保證了在最后提交階段之前各參與節(jié)點(diǎn)的狀態(tài)是一致的。
即 3PC 把 2PC 的準(zhǔn)備階段再次一分為二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個(gè)階段。當(dāng) CanCommit、PreCommit、DoCommit
的任意一個(gè)步驟失敗或者等待超時(shí),執(zhí)行RollBack。
2.5.3 MQ事務(wù)
利用消息中間件來(lái)異步完成事務(wù)的后半部分更新,實(shí)現(xiàn)系統(tǒng)的最終一致性。這個(gè)方式避免了像XA協(xié)議那樣的性能問題。
下面的圖中,使用MQ完成事務(wù)在分布式的另外一個(gè)子系統(tǒng)上的操作,保證了動(dòng)作一致性。
2.5.4 TCC事務(wù)
TCC事務(wù)是Try、Confirm、Cancel三種指令的縮寫,其邏輯模式類似于XA兩階段提交,但是實(shí)現(xiàn)方式是在代碼層面人為實(shí)現(xiàn)。2PC 和 3PC 都是數(shù)據(jù)庫(kù)層面的,而 TCC 是業(yè)務(wù)層面的分布式事務(wù)。
分布式事務(wù)除了上面提到的數(shù)據(jù)庫(kù)層面的操作外,還包括發(fā)送短信、郵件這種業(yè)務(wù)操作等,這時(shí)候 TCC 就有用武之地了!
圖中就是一個(gè)典型的分布式系統(tǒng)的原子性操作,涉及A、B、C三個(gè)服務(wù)的執(zhí)行。如果有一個(gè)服務(wù) try 出問題,整個(gè)事務(wù)管理器就執(zhí)行calcel,如果三個(gè)try都成功,才執(zhí)行confirm做正式提交。
2.5.5 最終補(bǔ)償機(jī)制,同于MQ事務(wù)
最后使用補(bǔ)償機(jī)制做最后的一致性保障,MQ方案盡量使用補(bǔ)償機(jī)制進(jìn)行保障。
以上就是分布式事務(wù)CAP兩階段提交及三階段提交詳解的詳細(xì)內(nèi)容,更多關(guān)于分布式事務(wù)CAP及兩階三階段提交的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Mybatis select記錄封裝的實(shí)現(xiàn)
這篇文章主要介紹了Mybatis select記錄封裝的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10SpringBoot定制化Starter實(shí)現(xiàn)方法
小伙伴們?cè)?jīng)可能都經(jīng)歷過整天寫著CURD的業(yè)務(wù),都沒寫過一些組件相關(guān)的東西,這篇文章記錄一下SpringBoot如何自定義一個(gè)Starter。原理和理論就不用多說(shuō)了,可以在網(wǎng)上找到很多關(guān)于該方面的資料,這里主要分享如何自定義2023-01-01SpringMVC中RequestMapping注解(作用、出現(xiàn)的位置、屬性)
這篇文章主要介紹了SpringMVC中RequestMapping注解(作用、出現(xiàn)的位置、屬性),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01Java開發(fā)實(shí)現(xiàn)飛機(jī)大戰(zhàn)
這篇文章主要為大家詳細(xì)介紹了Java開發(fā)實(shí)現(xiàn)飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05IDEA 重新導(dǎo)入依賴maven 命令 reimport的方法
這篇文章主要介紹了IDEA 重新導(dǎo)入依賴maven 命令 reimport的相關(guān)知識(shí),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04tomcat部署java web項(xiàng)目遇到的問題及解決方法
這篇文章主要介紹了tomcat部署java web項(xiàng)目遇到的問題及解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07