溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解

發(fā)布時(shí)間:2020-07-19 22:34:29 來(lái)源:網(wǎng)絡(luò) 閱讀:453 作者:架構(gòu)師追風(fēng) 欄目:編程語(yǔ)言

作者:張乘輝

前言

在微服務(wù)架構(gòu)體系下,我們可以按照業(yè)務(wù)模塊分層設(shè)計(jì),單獨(dú)部署,減輕了服務(wù)部署壓力,也解耦了業(yè)務(wù)的耦合,避免了應(yīng)用逐漸變成一個(gè)龐然怪物,從而可以輕松擴(kuò)展,在某些服務(wù)出現(xiàn)故障時(shí)也不會(huì)影響其它服務(wù)的正常運(yùn)行??傊⒎?wù)在業(yè)務(wù)的高速發(fā)展中帶給我們?cè)絹?lái)越多的優(yōu)勢(shì),但是微服務(wù)并不是十全十美,因此不能盲目過(guò)度濫用,它有很多不足,而且會(huì)給系統(tǒng)帶來(lái)一定的復(fù)雜度,其中伴隨而來(lái)的分布式事務(wù)問(wèn)題,是微服務(wù)架構(gòu)體系下必然需要處理的一個(gè)痛點(diǎn),也是業(yè)界一直關(guān)注的一個(gè)領(lǐng)域,因此也出現(xiàn)了諸如 CAP 和 BASE 等理論。

在今年年初,阿里開(kāi)源了一個(gè)分布式事務(wù)中間件,起初起名為 Fescar,后改名為 Seata,在它開(kāi)源之初,我就知道它肯定要火,因?yàn)檫@是一個(gè)解決痛點(diǎn)的開(kāi)源項(xiàng)目,Seata 一開(kāi)始就是沖著對(duì)業(yè)務(wù)無(wú)侵入與高性能方向走,這正是我們對(duì)解決分布式事務(wù)問(wèn)題迫切的需求。

分布式事務(wù)解決的方案有哪些?

目前分布式事務(wù)解決的方案主要有對(duì)業(yè)務(wù)無(wú)入qin和有入qin的方案,無(wú)入qin方案主要有基于數(shù)據(jù)庫(kù) XA 協(xié)議的兩段式提交(2PC)方案,它的優(yōu)點(diǎn)是對(duì)業(yè)務(wù)代碼無(wú)入qin,但是它的缺點(diǎn)也是很明顯:必須要求數(shù)據(jù)庫(kù)對(duì) XA 協(xié)議的支持,且由于 XA 協(xié)議自身的特點(diǎn),它會(huì)造成事務(wù)資源長(zhǎng)時(shí)間得不到釋放,鎖定周期長(zhǎng),而且在應(yīng)用層上面無(wú)法干預(yù),因此它性能很差,它的存在相當(dāng)于七傷拳那樣“傷人七分,損己三分”,因此在互聯(lián)網(wǎng)項(xiàng)目中并不是很流行這種解決方案。

為了這個(gè)彌補(bǔ)這種方案帶來(lái)性能低的問(wèn)題,大佬們又想出了很多種方案來(lái)解決,但這無(wú)一例外都需要通過(guò)在應(yīng)用層做手腳,即入qin業(yè)務(wù)的方式,比如很出名的 TCC 方案,基于 TCC 也有很多成熟的框架,如 ByteTCC、tcc-transaction 等。以及基于可靠消息的最終一致性來(lái)實(shí)現(xiàn),如 RocketMQ 的事務(wù)消息。

入qin代碼的方案是基于現(xiàn)有情形“迫不得已”才推出的解決方案,實(shí)際上它們實(shí)現(xiàn)起來(lái)非常不優(yōu)雅,一個(gè)事務(wù)的調(diào)用通常伴隨而來(lái)的是對(duì)該事務(wù)接口增加一系列的反向操作,比如 TCC 三段式提交,提交邏輯必然伴隨著回滾的邏輯,這樣的代碼會(huì)使得項(xiàng)目非常臃腫,維護(hù)成本高。

Seata 各模塊之間的關(guān)系

針對(duì)上面所說(shuō)的分布式事務(wù)解決方案的痛點(diǎn),那很顯然,我們理想的分布式事務(wù)解決方案肯定是性能要好而且要對(duì)業(yè)務(wù)無(wú)入qin,業(yè)務(wù)層上無(wú)需關(guān)心分布式事務(wù)機(jī)制的約束,Seata 正是往這個(gè)方向發(fā)展的,因此它非常值得期待,它將給我們的微服務(wù)架構(gòu)帶來(lái)質(zhì)的提升。

那 Seata 是怎么做到的呢?下面說(shuō)說(shuō)它的各個(gè)模塊之間的關(guān)系。

Seata 的設(shè)計(jì)思路是將一個(gè)分布式事務(wù)可以理解成一個(gè)全局事務(wù),下面掛了若干個(gè)分支事務(wù),而一個(gè)分支事務(wù)是一個(gè)滿足 ACID 的本地事務(wù),因此我們可以操作分布式事務(wù)像操作本地事務(wù)一樣。

Seata 內(nèi)部定義了 3個(gè)模塊來(lái)處理全局事務(wù)和分支事務(wù)的關(guān)系和處理過(guò)程,這三個(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é)開(kāi)啟一個(gè)全局事務(wù),并最終發(fā)起全局提交或全局回滾的決議。

?Resource Manager (RM):控制分支事務(wù),負(fù)責(zé)分支注冊(cè)、狀態(tài)匯報(bào),并接收事務(wù)協(xié)調(diào)器的指令,驅(qū)動(dòng)分支(本地)事務(wù)的提交和回滾。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


簡(jiǎn)要說(shuō)說(shuō)整個(gè)全局事務(wù)的執(zhí)行步驟:

1.TM 向 TC 申請(qǐng)開(kāi)啟一個(gè)全局事務(wù),TC 創(chuàng)建全局事務(wù)后返回全局唯一的 XID,XID 會(huì)在全局事務(wù)的上下文中傳播;

2.RM 向 TC 注冊(cè)分支事務(wù),該分支事務(wù)歸屬于擁有相同 XID 的全局事務(wù);

3.TM 向 TC 發(fā)起全局提交或回滾;

4.TC 調(diào)度 XID 下的分支事務(wù)完成提交或者回滾。

與 XA 方案有什么不同?

Seata 的事務(wù)提交方式跟 XA 協(xié)議的兩段式提交在總體上來(lái)說(shuō)基本是一致的,那它們之間有什么不同呢?

我們都知道 XA 協(xié)議它依賴的是數(shù)據(jù)庫(kù)層面來(lái)保障事務(wù)的一致性,也即是說(shuō) XA 的各個(gè)分支事務(wù)是在數(shù)據(jù)庫(kù)層面上驅(qū)動(dòng)的,由于 XA 的各個(gè)分支事務(wù)需要有 XA 的驅(qū)動(dòng)程序,一方面會(huì)導(dǎo)致數(shù)據(jù)庫(kù)與 XA 驅(qū)動(dòng)耦合,另一方面它會(huì)導(dǎo)致各個(gè)分支的事務(wù)資源鎖定周期長(zhǎng),這也是它沒(méi)有在互聯(lián)網(wǎng)公司流行的重要因素。

基于 XA 協(xié)議以上的問(wèn)題,Seata 另辟蹊徑,既然在依賴數(shù)據(jù)庫(kù)層會(huì)導(dǎo)致這么多問(wèn)題,那我就從應(yīng)用層做手腳,這還得從 Seata 的 RM 模塊說(shuō)起,前面也說(shuō)過(guò) RM 的主要作用了,其實(shí) RM 在內(nèi)部做了對(duì)數(shù)據(jù)庫(kù)操作的代理層,如下:

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


Seata 在數(shù)據(jù)源做了一層代理層,所以我們使用 Seata 時(shí),我們使用的數(shù)據(jù)源實(shí)際上用的是 Seata 自帶的數(shù)據(jù)源代理 DataSourceProxy,Seata 在這層代理中加入了很多邏輯,主要是解析 SQL,把業(yè)務(wù)數(shù)據(jù)在更新前后的數(shù)據(jù)鏡像組織成回滾日志,并將 undo log 日志插入 undo_log 表中,保證每條更新數(shù)據(jù)的業(yè)務(wù) sql 都有對(duì)應(yīng)的回滾日志存在。

這樣做的好處就是,本地事務(wù)執(zhí)行完可以立即釋放本地事務(wù)鎖定的資源,然后向 TC 上報(bào)分支狀態(tài)。當(dāng) TM 決議全局提交時(shí),就不需要同步協(xié)調(diào)處理了,TC 會(huì)異步調(diào)度各個(gè) RM 分支事務(wù)刪除對(duì)應(yīng)的 undo log 日志即可,這個(gè)步驟非常快速地可以完成;當(dāng) TM 決議全局回滾時(shí),RM 收到 TC 發(fā)送的回滾請(qǐng)求,RM 通過(guò) XID 找到對(duì)應(yīng)的 undo log 回滾日志,然后執(zhí)行回滾日志完成回滾操作。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


如上圖所示,XA 方案的 RM 是放在數(shù)據(jù)庫(kù)層的,它依賴了數(shù)據(jù)庫(kù)的 XA 驅(qū)動(dòng)程序。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


如上圖所示,Seata 的 RM 實(shí)際上是已中間件的形式放在應(yīng)用層,不用依賴數(shù)據(jù)庫(kù)對(duì)協(xié)議的支持,完全剝離了分布式事務(wù)方案對(duì)數(shù)據(jù)庫(kù)在協(xié)議支持上的要求。

分支事務(wù)如何提交和回滾?

下面詳細(xì)說(shuō)說(shuō)分支事務(wù)是如何提交和回滾的:

?第一階段:

分支事務(wù)利用 RM 模塊中對(duì) JDBC 數(shù)據(jù)源代理,加入了若干流程,對(duì)業(yè)務(wù) SQL 進(jìn)行解釋,把業(yè)務(wù)數(shù)據(jù)在更新前后的數(shù)據(jù)鏡像組織成回滾日志,并生成 undo log 日志,對(duì)全局事務(wù)鎖的檢查以及分支事務(wù)的注冊(cè)等,利用本地事務(wù) ACID 特性,將業(yè)務(wù) SQL 和 undo log 寫(xiě)入同一個(gè)事物中一同提交到數(shù)據(jù)庫(kù)中,保證業(yè)務(wù) SQL 必定存在相應(yīng)的回滾日志,最后對(duì)分支事務(wù)狀態(tài)向 TC 進(jìn)行上報(bào)。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


?第二階段:

TM決議全局提交:

當(dāng) TM 決議提交時(shí),就不需要同步協(xié)調(diào)處理了,TC 會(huì)異步調(diào)度各個(gè) RM 分支事務(wù)刪除對(duì)應(yīng)的 undo log 日志即可,這個(gè)步驟非常快速地可以完成。這個(gè)機(jī)制對(duì)于性能提升非常關(guān)鍵,我們知道正常的業(yè)務(wù)運(yùn)行過(guò)程中,事務(wù)執(zhí)行的成功率是非常高的,因此可以直接在本地事務(wù)中提交,這步對(duì)于提升性能非常顯著。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


TM決議全局回滾:

當(dāng) TM 決議回滾時(shí),RM 收到 TC 發(fā)送的回滾請(qǐng)求,RM 通過(guò) XID 找到對(duì)應(yīng)的 undo log 回滾日志,然后利用本地事務(wù) ACID 特性,執(zhí)行回滾日志完成回滾操作并刪除 undo log 日志,最后向 TC 進(jìn)行回滾結(jié)果上報(bào)。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


業(yè)務(wù)對(duì)以上所有的流程都無(wú)感知,業(yè)務(wù)完全不關(guān)心全局事務(wù)的具體提交和回滾,而且最重要的一點(diǎn)是 Seata 將兩段式提交的同步協(xié)調(diào)分解到各個(gè)分支事務(wù)中了,分支事務(wù)與普通的本地事務(wù)無(wú)任何差異,這意味著我們使用 Seata 后,分布式事務(wù)就像使用本地事務(wù)一樣,完全將數(shù)據(jù)庫(kù)層的事務(wù)協(xié)調(diào)機(jī)制交給了中間件層 Seata 去做了,這樣雖然事務(wù)協(xié)調(diào)搬到應(yīng)用層了,但是依然可以做到對(duì)業(yè)務(wù)的零侵入,從而剝離了分布式事務(wù)方案對(duì)數(shù)據(jù)庫(kù)在協(xié)議支持上的要求,且 Seata 在分支事務(wù)完成之后直接釋放資源,極大減少了分支事務(wù)對(duì)資源的鎖定時(shí)間,完美避免了 XA 協(xié)議需要同步協(xié)調(diào)導(dǎo)致資源鎖定時(shí)間過(guò)長(zhǎng)的問(wèn)題。

其它方案的補(bǔ)充

上面說(shuō)的其實(shí)是 Seata 的默認(rèn)模式,也叫 AT 模式,它是類似于 XA 方案的兩段式提交方案,并且是對(duì)業(yè)務(wù)無(wú)侵入,但是這種機(jī)制依然是需要依賴數(shù)據(jù)庫(kù)本地事務(wù)的 ACID 特性,有沒(méi)有發(fā)現(xiàn),我在上面的圖中都強(qiáng)調(diào)了必須是支持 ACID 特性的關(guān)系型數(shù)據(jù)庫(kù),那么問(wèn)題就來(lái)了,非關(guān)系型或者不支持 ACID 的數(shù)據(jù)庫(kù)就無(wú)法使用 Seata 了,別慌,Seata 現(xiàn)階段為我們準(zhǔn)備了另外一種模式,叫 MT 模式,它是一種對(duì)業(yè)務(wù)有入qin的方案,提交回滾等操作需要我們自行定義,業(yè)務(wù)邏輯需要被分解為 Prepare/Commit/Rollback 3 部分,形成一個(gè) MT 分支,加入全局事務(wù),它存在的意義是為 Seata 觸達(dá)更多的場(chǎng)景。

分布式事務(wù)解決方案,中間件 Seata 的設(shè)計(jì)原理詳解


只不過(guò),它不是 Seata “主打”的模式,它的存在僅僅作為補(bǔ)充的方案,從以上官方的發(fā)展遠(yuǎn)景就可以看出來(lái),Seata 的目標(biāo)是始終是對(duì)業(yè)務(wù)無(wú)入qin的方案。

最后
歡迎大家一起交流,喜歡文章記得點(diǎn)個(gè)贊喲,感謝支持!


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI