當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 程序員小灰
[導(dǎo)讀]對(duì)于分布式事務(wù),相信所有人都應(yīng)該很了解,為什么會(huì)有分布式事務(wù)?

對(duì)于分布式事務(wù),相信所有人都應(yīng)該很了解,為什么會(huì)有分布式事務(wù)?無(wú)論是數(shù)據(jù)量導(dǎo)致的分庫(kù),還是現(xiàn)在微服務(wù)盛行的場(chǎng)景都是他出現(xiàn)的原因。

這一篇內(nèi)容還是避免不了俗套,主要的范圍無(wú)非是XA、2PC、3PC、TCC,再最后到Seata。

但是,我認(rèn)為這東西,只是適用于面試和理論的了解,你真要說(shuō)這些方案實(shí)際生產(chǎn)中有人用嗎?

有,但是會(huì)實(shí)現(xiàn)的更簡(jiǎn)單,不會(huì)套用理論來(lái)實(shí)現(xiàn),大廠有大廠的解決方案,中小公司用框架或者壓根就不存在分布式事務(wù)的問題。

那,為什么還要寫這個(gè)?

為了你面試八股文啊,小可愛。

事務(wù)

要說(shuō)分布式事務(wù),首先還是從事務(wù)的基本特征說(shuō)起。

A原子性:在事務(wù)的執(zhí)行過(guò)程中,要么全部執(zhí)行成功,要么都不成功。

C一致性:事務(wù)在執(zhí)行前后,不能破壞數(shù)據(jù)的完整性。一致性更多的說(shuō)的是通過(guò)AID來(lái)達(dá)到目的,數(shù)據(jù)應(yīng)該符合預(yù)先的定義和約束,由應(yīng)用層面來(lái)保證,還有的說(shuō)法是C是強(qiáng)行為了ACID湊出來(lái)的。

I隔離性:多個(gè)事務(wù)之間是互相隔離的,事務(wù)之間不能互相干擾,涉及到不同事務(wù)的隔離級(jí)別的問題。

D持久性:一旦事務(wù)提交,數(shù)據(jù)庫(kù)中數(shù)據(jù)的狀態(tài)就應(yīng)該是永久性的。

XA

XA(eXtended Architecture)是指由X/Open 組織提出的分布式事務(wù)處理的規(guī)范,他是一個(gè)規(guī)范或者說(shuō)是協(xié)議,定義了事務(wù)管理器TM(Transaction Manager),資源管理器RM(Resource Manager),和應(yīng)用程序。

事務(wù)管理器TM就是事務(wù)的協(xié)調(diào)者,資源管理器RM可以認(rèn)為就是一個(gè)數(shù)據(jù)庫(kù)。

2PC

XA定義了規(guī)范,那么2PC和3PC就是他的具體實(shí)現(xiàn)方式。

2PC叫做二階段提交,分為投票階段和執(zhí)行階段兩個(gè)階段。

投票階段

TM向所有的參與者發(fā)送prepare請(qǐng)求,詢問是否可以執(zhí)行事務(wù),等待各個(gè)參與者的響應(yīng)。

這個(gè)階段可以認(rèn)為只是執(zhí)行了事務(wù)的SQL語(yǔ)句,但是還沒有提交。

如果都執(zhí)行成功了就返回YES,否則返回NO。

執(zhí)行階段

執(zhí)行階段就是真正的事務(wù)提交的階段,但是要考慮到失敗的情況。

如果所有的參與者都返回YES,那么就執(zhí)行發(fā)送commit命令,參與者收到之后執(zhí)行提交事務(wù)。

反之,只要有任意一個(gè)參與者返回的是NO的話,就發(fā)送rollback命令,然后執(zhí)行回滾的操作。

2PC的缺陷

  1. 同步阻塞,可以看到,在執(zhí)行事務(wù)的過(guò)程當(dāng)中,所有數(shù)據(jù)庫(kù)的資源都被鎖定,如果這時(shí)候有其他人來(lái)訪問這些資源,將會(huì)被阻塞,這是一個(gè)很大的性能問題。
  2. TM單點(diǎn)問題,只要一個(gè)TM,一旦TM宕機(jī),那么整個(gè)流程無(wú)法繼續(xù)完成。
  3. 數(shù)據(jù)不一致,如果在執(zhí)行階段,參與者腦裂或者其他故障導(dǎo)致沒有收到commit請(qǐng)求,部分提交事務(wù),部分未提交,那么數(shù)據(jù)不一致的問題就產(chǎn)生了。

3PC

既然2PC有這么多問題,所以就衍生出了3PC的概念,也叫做三階段提交,他把整個(gè)流程分成了CanCommit、PreCommit、DoCommit三個(gè)步驟,相比2PC,增加的就是CanCommit階段。

CanCommit

這個(gè)階段就是先詢問數(shù)據(jù)庫(kù)是否執(zhí)行事務(wù),發(fā)送一個(gè)canCommit的請(qǐng)求去詢問,如果可以的話就返回YES,反之返回NO。

PreCommit

這個(gè)階段就等同于2PC的投票階段了,發(fā)送preCommit命令,然后去執(zhí)行SQL事務(wù),成功就返回YES,反之返回NO。

但是,這個(gè)地方的區(qū)別在于參與者有了超時(shí)機(jī)制,如果參與者超時(shí)未收到doCommit命令的話,將會(huì)默認(rèn)去提交事務(wù)。

DoCommit

DoCommit階段對(duì)應(yīng)到2PC的執(zhí)行階段,如果上一個(gè)階段都是收到Y(jié)ES的話,那么就發(fā)送doCommit命令去提交事務(wù),反之則會(huì)發(fā)送abort命令去中斷事務(wù)的執(zhí)行。

相比2PC的改進(jìn)

對(duì)于2PC的同步阻塞的問題,我們可以看到因?yàn)?PC加入了參與者的超時(shí)機(jī)制,所以原來(lái)2PC的如果某個(gè)參與者故障導(dǎo)致的同步阻塞的問題時(shí)間縮短了,這是一個(gè)優(yōu)化,但是并沒有完全避免。

第二個(gè)單點(diǎn)故障的問題,同樣因?yàn)槌瑫r(shí)機(jī)制的引入,一定程度上也算是優(yōu)化了。

但是數(shù)據(jù)不一致的問題,這個(gè)始終沒有得到解決。

舉個(gè)栗子:

在PreCommit階段,某個(gè)參與者發(fā)生腦裂,無(wú)法收到TM的請(qǐng)求,這時(shí)候其他參與者執(zhí)行abort事務(wù)回滾,而腦裂的參與者超時(shí)之后繼續(xù)提交事務(wù),還是有可能發(fā)生數(shù)據(jù)不一致的問題。

那么,為什么要加入DoCommit這個(gè)階段呢?就是為了引入超時(shí)機(jī)制,事先我們先確認(rèn)數(shù)據(jù)庫(kù)是否都可以執(zhí)行事務(wù),如果都OK,那么才會(huì)進(jìn)入后面的步驟,所以既然都可以執(zhí)行,那么超時(shí)之后說(shuō)明發(fā)生了問題,就自動(dòng)提交事務(wù)。

TCC

TCC的模式叫做Try、Confirm、Cancel,實(shí)際上也就是2PC的一個(gè)變種而已。

實(shí)現(xiàn)這個(gè)模式,一個(gè)事務(wù)的接口需要拆分成3個(gè),也就是Try預(yù)占、Confirm確認(rèn)提交、最后Cancel回滾。

對(duì)于TCC來(lái)說(shuō),實(shí)際生產(chǎn)我基本上就沒看見過(guò)有人用,考慮到原因,首先是程序員的本身素質(zhì)參差不齊,多個(gè)團(tuán)隊(duì)協(xié)作你很難去約束別人按照你的規(guī)則來(lái)實(shí)現(xiàn),另外一點(diǎn)就是太過(guò)于復(fù)雜。

如果說(shuō)有簡(jiǎn)單的應(yīng)用的話,庫(kù)存的應(yīng)用或許可以算做是一個(gè)。

一般庫(kù)存的操作,很多實(shí)現(xiàn)方案里面都會(huì)會(huì)在下單的時(shí)候先預(yù)占庫(kù)存,下單成功之后再實(shí)際去扣減庫(kù)存,最終如果發(fā)生了異常再回退。

凍結(jié)、預(yù)占庫(kù)存就是2PC的準(zhǔn)備階段,真正下單成功去扣減庫(kù)存就是2PC的提交階段,回滾就是某個(gè)發(fā)生異常的回滾操作,只不過(guò)在應(yīng)用層面來(lái)實(shí)現(xiàn)了2PC的機(jī)制而已。

SAGA

Saga源于1987 年普林斯頓大學(xué)的 Hecto 和 Kenneth 發(fā)表的如何處理 long lived transaction(長(zhǎng)活事務(wù))論文。

主要思想就是將長(zhǎng)事務(wù)拆分成多個(gè)本地短事務(wù)。

如果全部執(zhí)行成功,就正常完成了,反之,則會(huì)按照相反的順序依次調(diào)用補(bǔ)償。

SAGA模式有兩種恢復(fù)策略:

  1. 向前恢復(fù),這個(gè)模式偏向于一定要成功的場(chǎng)景,失敗則會(huì)進(jìn)行重試
  2. 向后恢復(fù),也就是發(fā)生異常的子事務(wù)依次回滾補(bǔ)償

由于這個(gè)模式在國(guó)內(nèi)基本沒看見有誰(shuí)用的,不在贅述。

消息隊(duì)列

基于消息隊(duì)列來(lái)實(shí)現(xiàn)最終一致性的方案,這個(gè)相比前面的我個(gè)人認(rèn)為還稍微靠譜一點(diǎn),那些都是理論啊,正常生產(chǎn)的實(shí)現(xiàn)很少看見應(yīng)用。

基于消息隊(duì)列的可能真正在應(yīng)用的還稍微多一點(diǎn)。

一般來(lái)說(shuō)有兩種方式,基于本地消息表和依賴MQ本身的事務(wù)消息。

本地消息表的這個(gè)方案其實(shí)更復(fù)雜,實(shí)際上我也沒看到過(guò)真正誰(shuí)來(lái)用。這里我以RocketMQ的事務(wù)消息來(lái)舉例,這個(gè)方式相比本地消息表則更完全依賴MQ本身的特性做了解耦,釋放了業(yè)務(wù)開發(fā)的復(fù)雜工作量。

  1. 業(yè)務(wù)發(fā)起方,調(diào)用遠(yuǎn)程接口,向MQ發(fā)送一條半事務(wù)消息,MQ收到消息之后會(huì)返回給生產(chǎn)者一個(gè)ACK
  2. 生產(chǎn)者收到ACK之后,去執(zhí)行事務(wù),但是事務(wù)還沒有提交。
  3. 生產(chǎn)者會(huì)根據(jù)事務(wù)的執(zhí)行結(jié)果來(lái)決定發(fā)送commit提交或者rollback回滾到MQ
  4. 這一點(diǎn)是發(fā)生異常的情況,比如生產(chǎn)者宕機(jī)或者其他異常導(dǎo)致MQ長(zhǎng)時(shí)間沒有收到commit或者rollback的消息,這時(shí)候MQ會(huì)發(fā)起狀態(tài)回查。
  5. MQ如果收到的是commit的話就會(huì)去投遞消息,消費(fèi)者正常消費(fèi)消息即可。如果是rollback的話,則會(huì)在設(shè)置的固定時(shí)間期限內(nèi)去刪除消息。

這個(gè)方案基于MQ來(lái)保證消息事務(wù)的最終一致性,還算是一個(gè)比較合理的解決方案,只要保證MQ的可靠性就可以正常實(shí)施應(yīng)用,業(yè)務(wù)消費(fèi)方根據(jù)本身的消息重試達(dá)到最終一致性。

框架

以上說(shuō)的都是理論和自己實(shí)現(xiàn)的方式,那么分布式事務(wù)就沒有框架來(lái)解決我們的問題嗎?

有,其實(shí)還不少,但是沒有能扛旗者出現(xiàn),要說(shuō)有,阿里的開源框架Seata還有阿里云的GTS。

GTS(Global Transaction Service 全局事務(wù)服務(wù))是阿里云的中間件產(chǎn)品,只要你用阿里云,付錢就可以用GTS。

Seata(Simple Extensible Autonomous Transaction Architecture)則是開源的分布式事務(wù)框架,提供了對(duì)TCC、XA、Saga以及AT模式的支持。

那么,GTS和Seata有什么關(guān)系呢?

實(shí)際上最開始的時(shí)候他們都是基于阿里內(nèi)部的TXC(Taobao Transaction Constructor)分布式中間件產(chǎn)品,然后TXC經(jīng)過(guò)改造上了阿里云就叫做GTS。

之后阿里的中間件團(tuán)隊(duì)基于TXC和GTS做出了開源的Seata,其中AT(Automatic Transaction)模式就是GTS原創(chuàng)的方案。

至于現(xiàn)在的版本,可以大致認(rèn)為他們就是一樣的就行了,到2020年,GTS已經(jīng)全面兼容了Seata的 GA 版本。

圖片來(lái)自阿里云官網(wǎng)GTS

整個(gè)GTS或者Seata包含以下幾個(gè)核心組件:

  • Transaction Coordinator(TC):事務(wù)協(xié)調(diào)器,維護(hù)全局事務(wù)的運(yùn)行狀態(tài),負(fù)責(zé)協(xié)調(diào)并驅(qū)動(dòng)全局事務(wù)的提交或回滾。
  • Transaction Manager(TM):控制全局事務(wù)的邊界,負(fù)責(zé)開啟一個(gè)全局事務(wù),并最終發(fā)起全局提交或全局回滾的決議。
  • Resource Manager(RM):控制分支事務(wù),負(fù)責(zé)分支注冊(cè)、狀態(tài)匯報(bào),并接收事務(wù)協(xié)調(diào)器的指令,驅(qū)動(dòng)分支(本地)事務(wù)的提交和回滾。

無(wú)論對(duì)于TCC還是原創(chuàng)的AT模式的支持,整個(gè)分布式事務(wù)的原理其實(shí)相對(duì)來(lái)說(shuō)還是比較容易理解。

  1. 事務(wù)開啟時(shí),TM向TC注冊(cè)全局事務(wù),并且獲得全局事務(wù)XID
  2. 這時(shí)候多個(gè)微服務(wù)的接口發(fā)生調(diào)用,XID就會(huì)傳播到各個(gè)微服務(wù)中,每個(gè)微服務(wù)執(zhí)行事務(wù)也會(huì)向TC注冊(cè)分支事務(wù)。
  3. 之后TM就可以管理針對(duì)每個(gè)XID的事務(wù)全局提交和回滾,RM完成分支的提交或者回滾。
核心組件定義-圖片來(lái)自阿里云官網(wǎng)

AT模式

原創(chuàng)的AT模式相比起TCC的方案來(lái)說(shuō),無(wú)需自己實(shí)現(xiàn)多個(gè)接口,通過(guò)代理數(shù)據(jù)源的形式生成更新前后的UNDO_LOG,依靠UNDO_LOG來(lái)實(shí)現(xiàn)回滾的操作。

執(zhí)行的流程如下:

  1. TM向TC注冊(cè)全局事務(wù),獲得XID
  2. RM則會(huì)去代理JDBC數(shù)據(jù)源,生成鏡像的SQL,形成UNDO_LOG,然后向TC注冊(cè)分支事務(wù),把數(shù)據(jù)更新和UNDO_LOG在本地事務(wù)中一起提交
  3. TC如果收到commit請(qǐng)求,則會(huì)異步去刪除對(duì)應(yīng)分支的UNDO_LOG,如果是rollback,就去查詢對(duì)應(yīng)分支的UNDO_LOG,通過(guò)UNDO_LOG來(lái)執(zhí)行回滾
事務(wù)模式-AT-圖片來(lái)自阿里云官網(wǎng)

TCC模式

相比AT模式代理JDBC數(shù)據(jù)源生成UNDO_LOG來(lái)生成逆向SQL回滾的方式,TCC就更簡(jiǎn)單一點(diǎn)了。

  1. TM向TC注冊(cè)全局事務(wù),獲得XID
  2. RM向TC注冊(cè)分支事務(wù),然后執(zhí)行Try方法,同時(shí)上報(bào)Try方法執(zhí)行情況
  3. 然后如果收到TC的commit請(qǐng)求就執(zhí)行Confirm方法,收到rollback則執(zhí)行Cancel
事務(wù)模式-TCC-圖片來(lái)自阿里云官網(wǎng)

XA模式

  1. TM向TC注冊(cè)全局事務(wù),獲得XID
  2. RM向TC注冊(cè)分支事務(wù),XA Start,執(zhí)行SQL,XA END,XA Prepare,然后上報(bào)分支執(zhí)行情況
  3. 然后如果收到TC的commit請(qǐng)求就執(zhí)行Confirm方法,收到rollback則執(zhí)行Cancel
事務(wù)模式-XA-圖片來(lái)自阿里云官網(wǎng)

SAGA模式

  1. TM向TC注冊(cè)全局事務(wù),獲得XID
  2. RM向TC注冊(cè)分支事務(wù),然后執(zhí)行業(yè)務(wù)方法,并且上報(bào)分支執(zhí)行情況
  3. RM收到分支回滾,執(zhí)行對(duì)應(yīng)的業(yè)務(wù)回滾方法
事務(wù)模式-Saga-圖片來(lái)自阿里云官網(wǎng)

總結(jié)

這里從事務(wù)的ACID開始,向大家先說(shuō)了XA是分布式事務(wù)處理的規(guī)范,之后談到2PC和3PC,2PC有同步阻塞、單點(diǎn)故障和數(shù)據(jù)不一致的問題,3PC在一定程度上解決了同步阻塞和單點(diǎn)故障的問題,但是還是沒有完全解決數(shù)據(jù)不一致的問題。

之后說(shuō)到TCC、SAGA、消息隊(duì)列的最終一致性的方案,TCC由于實(shí)現(xiàn)過(guò)于麻煩和復(fù)雜,業(yè)務(wù)很少應(yīng)用,SAGA了解即可,國(guó)內(nèi)也很少有應(yīng)用到的,消息隊(duì)列提供了解耦的實(shí)現(xiàn)方式,對(duì)于中小公司來(lái)說(shuō)可能是較為低成本的實(shí)現(xiàn)方式。

最后再說(shuō)目前國(guó)內(nèi)的實(shí)現(xiàn)框架,云端阿里云的GTS兼容Seata,非云端使用Seata,它提供了XA、TCC、AT、SAGA的解決方案,可以說(shuō)是目前的主流選擇。


免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。文章僅代表作者個(gè)人觀點(diǎn),不代表本平臺(tái)立場(chǎng),如有問題,請(qǐng)聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國(guó)汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來(lái)越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來(lái)越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽(yáng)舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國(guó)國(guó)際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語(yǔ)權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營(yíng)業(yè)績(jī)穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤(rùn)率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長(zhǎng) 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競(jìng)爭(zhēng)力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競(jìng)爭(zhēng)優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營(yíng)商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國(guó)電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長(zhǎng)三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡(jiǎn)稱"軟通動(dòng)力")與長(zhǎng)三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉