9秒旋、架構(gòu)設(shè)計-分布式事務(wù)

一、產(chǎn)生背景

????????為了應(yīng)對互聯(lián)網(wǎng)環(huán)境帶來了海量的數(shù)據(jù)容量诀拭、連接數(shù)與訪問量迁筛,通過數(shù)據(jù)拆分實現(xiàn)數(shù)據(jù)庫能力的線性擴展,通過微服務(wù)將復(fù)雜的單體應(yīng)用拆分為若干個功能簡單耕挨、松耦合的服務(wù)细卧。系統(tǒng)微服務(wù)化后,一個看似簡單的功能筒占,內(nèi)部可能需要調(diào)用多個服務(wù)并操作多個數(shù)據(jù)庫實現(xiàn)贪庙,服務(wù)調(diào)用的分布式事務(wù)問題變的非常突出。分布式事務(wù)已經(jīng)成為微服務(wù)落地最大的阻礙翰苫,也是最具挑戰(zhàn)性的一個技術(shù)難題止邮。 為此,本文將深入和大家探討微服務(wù)架構(gòu)下奏窑,分布式事務(wù)的各種解決方案导披。

二、理論基礎(chǔ)

1良哲、ACID

????????事務(wù)(Transaction)是由一系列對系統(tǒng)中數(shù)據(jù)進行訪問與更新的操作所組成的一個程序執(zhí)行邏輯單元(Unit)盛卡,狹義上的事務(wù)特指數(shù)據(jù)庫事務(wù)。一方面筑凫,當(dāng)多個應(yīng)用程序并發(fā)訪問數(shù)據(jù)庫時滑沧,事務(wù)可以在這些應(yīng)用程序之間提供一個隔離方法,以防止彼此的操作互相干擾巍实。另一方面滓技,事務(wù)為數(shù)據(jù)庫操作序列提供了一個從失敗中恢復(fù)到正常狀態(tài)的方法,同時提供了數(shù)據(jù)庫即使在異常狀態(tài)下仍能保持數(shù)據(jù)一致性的方法棚潦。事務(wù)具有四個特征令漂,簡稱為事務(wù)的ACID特性。

????? 原子性(Atomicity):事務(wù)作為一個整體被執(zhí)行丸边,包含在其中的對數(shù)據(jù)庫的操作要么全部被執(zhí)行叠必,要么都不執(zhí)行。

????? 一致性(Consistency):事務(wù)應(yīng)確保數(shù)據(jù)庫的狀態(tài)從一個一致狀態(tài)轉(zhuǎn)變?yōu)榱硪粋€一致狀態(tài)妹窖。一致狀態(tài)的含義是數(shù)據(jù)庫中的數(shù)據(jù)應(yīng)滿足完整性約束纬朝。

????? 隔離性(Isolation):多個事務(wù)并發(fā)執(zhí)行時,一個事務(wù)的執(zhí)行不應(yīng)影響其他事務(wù)的執(zhí)行骄呼。

????? 持久性(Durability):已被提交的事務(wù)對數(shù)據(jù)庫的修改應(yīng)該永久保存在數(shù)據(jù)庫中共苛。

2判没、CAP定理

CAP定理是由加州大學(xué)伯克利分校Eric Brewer教授提出來的,他指出WEB服務(wù)無法同時滿足一下3個屬性:

????????? 一致性(Consistency) : 客戶端知道一系列的操作都會同時發(fā)生(生效)

????????? 可用性(Availability) : 每個操作都必須以可預(yù)期的響應(yīng)結(jié)束

????????? 分區(qū)容錯性(Partition tolerance) : 即使出現(xiàn)單個組件無法可用,操作依然可以完成

????????具體地講在分布式系統(tǒng)中隅茎,在任何數(shù)據(jù)庫設(shè)計中澄峰,一個Web應(yīng)用至多只能同時支持上面的兩個屬性。顯然辟犀,任何橫向擴展策略都要依賴于數(shù)據(jù)分區(qū)俏竞。因此,設(shè)計人員必須在一致性與可用性之間做出選擇踪蹬。這個定理在迄今為止的分布式系統(tǒng)中都是適用的胞此!

3、BASE理論

????????在分布式系統(tǒng)中跃捣,我們往往追求的是可用性漱牵,它的重要程序比一致性要高,那么如何實現(xiàn)高可用性呢? 前人已經(jīng)給我們提出來了另外一個理論,就是BASE理論牲迫,它是用來對CAP定理進行進一步擴充的印荔。BASE理論指的是:

????? Basically Available(基本可用)

????? Soft state(軟狀態(tài))

????? Eventually consistent(最終一致性)

????????BASE理論是對CAP中的一致性和可用性進行一個權(quán)衡的結(jié)果蘑拯,理論的核心思想就是:我們無法做到強一致,但每個應(yīng)用都可以根據(jù)自身的業(yè)務(wù)特點,采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達到最終一致性(Eventual consistency)。

4铆农、2PC

?????????兩階段提交,是實現(xiàn)分布式事務(wù)的成熟方案狡耻。第一階段是表決階段墩剖,是所有參與者都將本事務(wù)能否成功的反饋發(fā)給協(xié)調(diào)者;第二階段是執(zhí)行階段夷狰,協(xié)調(diào)者根據(jù)所有參與者的反饋岭皂,通知所有參與者,步調(diào)一致地在所有分支上提交沼头,或者在所有分支上回滾爷绘。

????????兩階段提交可以滿足ACID,但代價是吞吐量进倍。例如土至,數(shù)據(jù)庫需要頻繁地對資源上鎖等等。而且更致命的是猾昆,資源被鎖住的時間相對較長----在第一階段即需要上鎖毙籽,第二階段才能解鎖,依賴于所有分支的最慢者----這期間沒有任何人可以對該資源進行修改毡庆。

????????兩階段提交理論的一個廣泛工業(yè)應(yīng)用是XA協(xié)議坑赡。目前幾乎所有收費的商業(yè)數(shù)據(jù)庫都支持XA協(xié)議。XA協(xié)議已在業(yè)界成熟運行數(shù)十年么抗,但目前它在互聯(lián)網(wǎng)海量流量的應(yīng)用場景中毅否,吞吐量這個瓶頸變得十分致命,因此很少被用到蝇刀。

5螟加、TCC

????????TCC(Try、Confirm吞琐、Cancel)是兩階段提交的一個變種捆探。TCC提供了一個框架,需要應(yīng)用程序按照該框架編程站粟,將業(yè)務(wù)邏輯的每個分支都分為Try黍图、Confirm、Cancel三個操作集奴烙。TCC讓應(yīng)用程序自己定義數(shù)據(jù)庫操作的粒度助被,使得降低鎖沖突、提高吞吐量成為可能切诀。以一個典型的訂單為例揩环,按照TCC框架,應(yīng)用需要在Try階段將商品的庫存減去幅虑,將買家賬戶中的相應(yīng)金額扣掉丰滑,在臨時表中記錄下商品的數(shù)量,訂單的金額等信息倒庵;另外再編寫Confirm的邏輯褒墨,即在臨時表中刪除相關(guān)記錄,生成訂單哄芜,告知CRM貌亭、物流等系統(tǒng),等等认臊;以及Cancel邏輯圃庭,即恢復(fù)庫存和買家賬戶金額,刪除臨時表相關(guān)記錄失晴。

????????最終一致性是指事務(wù)進行中剧腻,某些分支的中間狀態(tài)可以被事務(wù)外觀察到,即"讀未提交"涂屁,從而導(dǎo)致多個分支的狀態(tài)可能不一致书在,但所有分支 最終 會達到要么全部提交,要么全部回滾的一致狀態(tài)拆又。很明顯儒旬,最終一致性部分犧牲了ACID中的C和I栏账,但它帶來了可觀的收益:資源不再需要長時間上鎖,極大地提高了吞吐量栈源。最終一致性在互聯(lián)網(wǎng)應(yīng)用場景中被廣泛用做吞吐量和ACID的妥協(xié)點挡爵。

三、解決方案

1甚垦、兩階段提交(2PC)

????XA 是指由 X/Open 組織提出的分布式事務(wù)處理的規(guī)范茶鹃。XA規(guī)范主要定義了Transaction Manager(TM)和Resource Manager(RM)之間的接口,結(jié)構(gòu)如下圖所示艰亮。

????????XA協(xié)議的流程可大致分為三個步驟:

????????步驟1:AP向TM創(chuàng)建全局事務(wù)闭翩,TM向APP返回全局事務(wù)號。

????????步驟2:APP使用全局事務(wù)號迄埃,訪問RM的資源(當(dāng)RM為數(shù)據(jù)庫時疗韵,資源訪問就是SQL操作)。當(dāng)RM第一次收到訪問時调俘,使用該全局事務(wù)號向TM注冊伶棒,TM返回事務(wù)分支事務(wù)號。

????????步驟3:AP向TM發(fā)出全局事務(wù)提交請求彩库,TM與參與事務(wù)的RM通信肤无,進行提交處理,全部完成后骇钦,向AP返回結(jié)果宛渐。

????????TM與RM之間的提交處理,采用兩階段提交協(xié)議眯搭。TM在第一階段對所有的參與事務(wù)的RM請求“預(yù)備”操作窥翩,達成關(guān)于分布式事務(wù)一致性的共識。事務(wù)參與者必須完成所有的約束檢查鳞仙,并且確保后續(xù)提交或放棄時所需要的數(shù)據(jù)已持久化寇蚊。在第二階段,根據(jù)之前達到的提交或放棄的共識棍好,請求所有參事務(wù)的RM完成相應(yīng)的操作仗岸。

????????提交事務(wù)的過程中需要在多個資源節(jié)點之間進行協(xié)調(diào),而各節(jié)點對鎖資源的釋放必須等到事務(wù)最終提交時借笙,所以兩階段提交在執(zhí)行同樣的事務(wù)時會比一階段提交消耗更多的時間扒怖。當(dāng)事務(wù)并發(fā)量達到一定數(shù)量時,就會出現(xiàn)大量事務(wù)積壓甚至出現(xiàn)死鎖业稼,系統(tǒng)性能和處理吞吐量就會嚴重下滑盗痒。

2、補償事務(wù)(TCC)

????????TCC模式為全局事務(wù)執(zhí)行提供了一個框架低散,開發(fā)人員只需要實現(xiàn)每個事務(wù)分支的回滾俯邓,不需要記錄整個事務(wù)流程的操作日志骡楼。TCC 其實就是采用的補償機制,其核心思想是:針對每個操作看成,都要注冊一個與其對應(yīng)的確認和補償(撤銷)操作君编。它分為三個階段:

????? Try 階段主要是對業(yè)務(wù)系統(tǒng)做檢測及資源預(yù)留;

????? Confirm 階段主要是對業(yè)務(wù)系統(tǒng)做確認提交川慌,Try階段執(zhí)行成功并開始執(zhí)行 Confirm階段時,默認 Confirm階段是不會出錯的祠乃。即:只要Try成功梦重,Confirm一定成功。在這個階段真正執(zhí)行亮瓷,不做業(yè)務(wù)檢查琴拧。

????? Cancel 階段主要是在業(yè)務(wù)執(zhí)行錯誤,需要回滾的狀態(tài)下執(zhí)行的業(yè)務(wù)取消嘱支,預(yù)留資源釋放蚓胸。

TCC模式結(jié)構(gòu)如下圖。

? ??說明:

????????? 一個完整的業(yè)務(wù)活動由一個主業(yè)務(wù)服務(wù)與若干從業(yè)務(wù)服務(wù)組成除师。

????????? 主業(yè)務(wù)服務(wù)負責(zé)發(fā)起并完成整個業(yè)務(wù)活動沛膳。

?????????? 從業(yè)務(wù)服務(wù)提供TCC型業(yè)務(wù)操作。

? ? ? ?? 業(yè)務(wù)活動管理器控制業(yè)務(wù)活動的一致性汛聚,它登記業(yè)務(wù)活動中的操作锹安,并在業(yè)務(wù)活動提交時確認所有的TCC型操作的confirm操作,在業(yè)務(wù)活動取消時調(diào)用所有TCC型操作的cancel操作倚舀。

????????TCC業(yè)務(wù)包括兩個階段完成:

????????? 第一階段:主業(yè)務(wù)服務(wù)分別調(diào)用所有從業(yè)務(wù)的 try 操作叹哭,并在活動管理器中登記所有從業(yè)務(wù)服務(wù)。當(dāng)所有從業(yè)務(wù)服務(wù)的 try 操作都調(diào)用成功或者某個從業(yè)務(wù)服務(wù)的 try 操作失敗痕貌,進入第二階段风罩。

????????? 第二階段:活動管理器根據(jù)第一階段的執(zhí)行結(jié)果來執(zhí)行 confirm 或 cancel 操作。

????????如果第一階段所有 try 操作都成功舵稠,則活動管理器調(diào)用所有從業(yè)務(wù)活動的 confirm操作超升。否則調(diào)用所有從業(yè)務(wù)服務(wù)的 cancel 操作。

????????使用TCC時要注意Try - Confirm - Cancel 3個操作的冪等控制柱查,網(wǎng)絡(luò)原因廓俭,或者重試操作都有可能導(dǎo)致這幾個操作的重復(fù)執(zhí)行。

3唉工、本地消息表(異步確保)

????????本地消息表這種實現(xiàn)方式應(yīng)該是業(yè)界使用最多的研乒,其核心思想是將分布式事務(wù)拆分成本地事務(wù)進行處理這種思路是來源于ebay。我們可以從下面的流程圖中看出其中的一些細節(jié):

????????基本思路就是:

????????消息生產(chǎn)方淋硝,需要額外建一個消息表雹熬,并記錄消息發(fā)送狀態(tài)宽菜。消息表和業(yè)務(wù)數(shù)據(jù)要在一個事務(wù)里提交,也就是說他們要在一個數(shù)據(jù)庫里面竿报。然后消息會經(jīng)過MQ發(fā)送到消息的消費方铅乡。如果消息發(fā)送失敗,會進行重試發(fā)送烈菌。

????????消息消費方阵幸,需要處理這個消息,并完成自己的業(yè)務(wù)邏輯芽世。此時如果本地事務(wù)處理成功挚赊,表明已經(jīng)處理成功了,如果處理失敗济瓢,那么就會重試執(zhí)行荠割。如果是業(yè)務(wù)上面的失敗,可以給生產(chǎn)方發(fā)送一個業(yè)務(wù)補償消息旺矾,通知生產(chǎn)方進行回滾等操作蔑鹦。

????????生產(chǎn)方和消費方定時掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發(fā)送一遍箕宙。如果有靠譜的自動對賬補賬邏輯嚎朽,這種方案還是非常實用的。

????????這種方案遵循BASE理論扒吁,采用的是最終一致性火鼻,筆者認為是這幾種方案里面比較適合實際業(yè)務(wù)場景的,即不會出現(xiàn)像2PC那樣復(fù)雜的實現(xiàn)(當(dāng)調(diào)用鏈很長的時候雕崩,2PC的可用性是非常低的)魁索,也不會像TCC那樣可能出現(xiàn)確認或者回滾不了的情況。

4盼铁、MQ事務(wù)消息

????????有一些第三方的MQ是支持事務(wù)消息的粗蔚,比如RocketMQ,他們支持事務(wù)消息的方式也是類似于采用的二階段提交饶火,但是市面上一些主流的MQ都是不支持事務(wù)消息的鹏控,比如 RabbitMQ 和 Kafka 都不支持。

????????以阿里的 RocketMQ 中間件為例肤寝,其思路大致為:

????????第一階段Prepared消息当辐,會拿到消息的地址。第二階段執(zhí)行本地事務(wù)鲤看,第三階段通過第一階段拿到的地址去訪問消息缘揪,并修改狀態(tài)。

????????也就是說在業(yè)務(wù)方法內(nèi)要想消息隊列提交兩次請求,一次發(fā)送消息和一次確認消息找筝。如果確認消息發(fā)送失敗了RocketMQ會定期掃描消息集群中的事務(wù)消息蹈垢,這時候發(fā)現(xiàn)了Prepared消息,它會向消息發(fā)送者確認袖裕,所以生產(chǎn)方需要實現(xiàn)一個check接口曹抬,RocketMQ會根據(jù)發(fā)送端設(shè)置的策略來決定是回滾還是繼續(xù)發(fā)送確認消息。這樣就保證了消息發(fā)送與本地事務(wù)同時成功或同時失敗急鳄。

????MQ事務(wù)消息的一種可能實現(xiàn)的結(jié)構(gòu)如下圖谤民。

????說明:

????????1)業(yè)務(wù)處理服務(wù)在業(yè)務(wù)事務(wù)提交前,向?qū)崟r消息服務(wù)請求發(fā)送消息攒岛,實時消息服務(wù)只記錄消息數(shù)據(jù)赖临,而不真正發(fā)送。

????????2)業(yè)務(wù)處理服務(wù)在業(yè)務(wù)事務(wù)提交后灾锯,向?qū)崟r消息服務(wù)確認發(fā)送。只有在得到確認發(fā)送指令后嗅榕,實時消息服務(wù)才真正發(fā)送消息顺饮。

????????3)業(yè)務(wù)處理服務(wù)在業(yè)務(wù)事務(wù)回滾后,向?qū)崟r消息服務(wù)取消發(fā)送凌那。

????????4)消息狀態(tài)確認系統(tǒng)定期找到未確認發(fā)送或回滾發(fā)送的消息兼雄,向業(yè)務(wù)處理服務(wù)詢問消息狀態(tài),業(yè)務(wù)處理服務(wù)根據(jù)消息ID或消息內(nèi)容確定該消息是否有效帽蝶。

????????通過消息進行事務(wù)異步的方式赦肋,可以保證業(yè)務(wù)數(shù)據(jù)操作和消息的發(fā)送同時執(zhí)行成功或失敗,保持了事務(wù)的最終一致性励稳。

????????采用可靠消息的方式佃乘,在兩個事務(wù)間實現(xiàn)分布式事務(wù)時,可以很好地滿足事務(wù)最終一致性以及事務(wù)的回滾驹尼,但如果一個事務(wù)上下文中超過兩個事務(wù)操作后趣避,需要開發(fā)人員實現(xiàn)整個事務(wù)流程的操作日志的記錄、每個事務(wù)分支的回滾以及整個流程的準確調(diào)度新翎。

5程帕、SAGA事務(wù)模型

? ??????Saga事務(wù)模型又叫做長時間運行的事務(wù)(Long-running-transaction), 它是由普林斯頓大學(xué)的H.Garcia-Molina等人提出,它描述的是另外一種在沒有兩階段提交的的情況下解決分布式系統(tǒng)中復(fù)雜的業(yè)務(wù)事務(wù)問題地啰。

????????我們這里說的是一種基于 Sagas 機制的工作流事務(wù)模型愁拭。該模型其核心思想就是拆分分布式系統(tǒng)中的長事務(wù)為多個短事務(wù),或者叫多個本地事務(wù)亏吝,然后由 Sagas 工作流引擎負責(zé)協(xié)調(diào)岭埠,如果整個流程正常結(jié)束,那么就算是業(yè)務(wù)成功完成,如果在這過程中實現(xiàn)失敗枫攀,那么Sagas工作流引擎就會以相反的順序調(diào)用補償操作括饶,重新進行業(yè)務(wù)回滾。

四来涨、開源軟件Seata

1图焰、簡介

????????2007 開始,螞蟻金服自主研發(fā)分布式事務(wù)分布式事務(wù)中間件 XTS(eXtended Transaction Service)蹦掐,在內(nèi)部廣泛應(yīng)用并解決金融核心場景下的跨數(shù)據(jù)庫技羔、跨服務(wù)數(shù)據(jù)一致性問題,最終以 DTX(Distributed Transaction eXtended)的云產(chǎn)品化展現(xiàn)并對外開放卧抗。與此同時藤滥,阿里巴巴中間件團隊發(fā)布 TXC(Taobao Transaction Constructor),為集團內(nèi)應(yīng)用提供分布式事務(wù)服務(wù)社裆,經(jīng)過多年的技術(shù)沉淀拙绊,于 2016 年產(chǎn)品化改造為 GTS(Global Transaction Service),通過阿里云解決方案在眾多外部客戶中落地實施泳秀。

????????2019 年 1 月标沪,基于技術(shù)積累,阿里巴巴中間件團隊發(fā)起了開源項目 Fescar(Fast & EaSy Commit And Rollback, Fescar)嗜傅,和社區(qū)一起共建分布式事務(wù)解決方案金句。Fescar 為解決微服務(wù)架構(gòu)下的分布式事務(wù)問題交出了一份與眾不同的答卷。而 Fescar 的愿景是讓分布式事務(wù)的使用像本地事務(wù)的使用一樣簡單和高效吕嘀。最終的目標是希望可以讓 Fescar 適用于所有的分布式事務(wù)場景违寞。

????????為了達到適用于更多的分布式事務(wù)業(yè)務(wù)場景的目標,螞蟻金服加入 Fescar 社區(qū)共建偶房,在 Fescar 0.4.0 版本中加入了 TCC 模式趁曼。螞蟻金服的加入引發(fā)了社區(qū)核心成員的討論,為了達到適用于所有的分布式事務(wù)業(yè)務(wù)場景的目標蝴悉,也為了社區(qū)更中立彰阴、更開放、生態(tài)更加豐富拍冠,社區(qū)核心成員們決定進行品牌升級尿这,改名 Seata。Seata 意為:Simple Extensible Autonomous Transaction Architecture庆杜,是一套一站式分布式事務(wù)解決方案射众。

2、架構(gòu)

下圖描述了GTS一種可能的實現(xiàn)架構(gòu)晃财。

????????與XA架構(gòu)相同叨橱,GTS架構(gòu)由應(yīng)用典蜕、事務(wù)管理器、資源管理器三個部分組成罗洗。資源管理器由事務(wù)分支處理模塊愉舔、鏡像查詢構(gòu)造模塊、并發(fā)控制模塊伙菜、恢復(fù)控制模塊轩缤,以及存儲在數(shù)據(jù)庫中的GTS事務(wù)信息(GTS鎖表與GTS日志表)等組成。

?????事務(wù)分支處理模塊:是資源管理器的外部接口贩绕,并完成內(nèi)部各模塊的調(diào)用火的。

? ? ?鏡像查詢構(gòu)造模塊:從Insert、Update淑倾、Delete語句馏鹤,生成該操作對應(yīng)記錄集的鏡像查詢語句。例如table_name表包含兩個字段column1和column2娇哆,column1為主鍵湃累,則鏡像查詢語句為select column1, column2 from table_name where column1=v1。

?????并發(fā)控制模塊:基于GTS事務(wù)鎖表碍讨,維護讀寫并發(fā)控制脱茉。

?????恢復(fù)控制模塊:基于GTS日志表,進行故障恢復(fù)垄开。

3、內(nèi)部運行機制

AT(Automatic Transaction)模式

????????Seata AT模式是基于XA事務(wù)演進而來的一個分布式事務(wù)中間件税肪,XA是一個基于數(shù)據(jù)庫實現(xiàn)的分布式事務(wù)協(xié)議溉躲,本質(zhì)上和兩階段提交一樣,需要數(shù)據(jù)庫支持益兄,Mysql5.6以上版本支持XA協(xié)議锻梳,其他數(shù)據(jù)庫如Oracle,DB2也實現(xiàn)了XA接口净捅。核心思路是把一個分布式事務(wù)理解成一個包含了若干分支事務(wù)的全局事務(wù)疑枯。全局事務(wù)的職責(zé)是協(xié)調(diào)其下管轄的分支事務(wù)達成一致,要么一起成功提交蛔六,要么一起失敗回滾荆永。定義 3 個組件來協(xié)議分布式事務(wù)的處理過程。

Transaction Coordinator (TC):?事務(wù)協(xié)調(diào)器国章,維護全局事務(wù)的運行狀態(tài)具钥,負責(zé)協(xié)調(diào)并驅(qū)動全局事務(wù)的提交或回滾。

Transaction Manager (TM):?控制全局事務(wù)的邊界液兽,負責(zé)開啟一個全局事務(wù)骂删,并最終發(fā)起全局提交或全局回滾的決議。

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

一個典型的分布式事務(wù)過程:

1)TM 向 TC 申請開啟一個全局事務(wù)眷射,全局事務(wù)創(chuàng)建成功并生成一個全局唯一的 XID。

2)XID 在微服務(wù)調(diào)用鏈路的上下文中傳播恋追。

3)RM 向 TC 注冊分支事務(wù)凭迹,將其納入 XID 對應(yīng)全局事務(wù)的管轄。

4)TM 向 TC 發(fā)起針對 XID 的全局提交或回滾決議苦囱。

5)TC 調(diào)度 XID 下管轄的全部分支事務(wù)完成提交或回滾請求嗅绸。

1)第一階段

????????Seata 的 JDBC 數(shù)據(jù)源代理通過對業(yè)務(wù) SQL 的解析,把業(yè)務(wù)數(shù)據(jù)在更新前后的數(shù)據(jù)鏡像組織成回滾日志撕彤,利用 本地事務(wù) 的 ACID 特性鱼鸠,將業(yè)務(wù)數(shù)據(jù)的更新和回滾日志的寫入在同一個 本地事務(wù) 中提交。這樣羹铅,可以保證:任何提交的業(yè)務(wù)數(shù)據(jù)的更新一定有相應(yīng)的回滾日志存在蚀狰。

????????基于這樣的機制,分支的本地事務(wù)便可以在全局事務(wù)的第一階段提交职员,并馬上釋放本地事務(wù)鎖定的資源麻蹋。這也是Seata和XA事務(wù)的不同之處,兩階段提交往往對資源的鎖定需要持續(xù)到第二階段實際的提交或者回滾操作焊切,而有了回滾日志之后扮授,可以在第一階段釋放對資源的鎖定,降低了鎖范圍专肪,提高效率刹勃,即使第二階段發(fā)生異常需要回滾,只需找對undolog中對應(yīng)數(shù)據(jù)并反解析成sql來達到回滾目的嚎尤。同時Seata通過代理數(shù)據(jù)源將業(yè)務(wù)sql的執(zhí)行解析成undolog來與業(yè)務(wù)數(shù)據(jù)的更新同時入庫荔仁,達到了對業(yè)務(wù)無侵入的效果。

2)第二階段

????如果決議是全局提交芽死,此時分支事務(wù)此時已經(jīng)完成提交乏梁,不需要同步協(xié)調(diào)處理(只需要異步清理回滾日志),Phase2 可以非呈毡迹快速地完成掌呜。

????????如果決議是全局回滾,RM 收到協(xié)調(diào)器發(fā)來的回滾請求坪哄,通過 XID 和 Branch ID 找到相應(yīng)的回滾日志記錄质蕉,通過回滾記錄生成反向的更新 SQL 并執(zhí)行势篡,以完成分支的回滾。

???????AT模型中有一個?重要前提:分支事務(wù)中涉及的資源模暗,必須?是支持ACID事務(wù)的關(guān)系型數(shù)據(jù)庫禁悠。分支的提交和回滾機制,都依賴于本地事務(wù)的保障兑宇。所以碍侦,如果應(yīng)用使用的數(shù)據(jù)庫是不支持事務(wù)的,或根本不是關(guān)系型數(shù)據(jù)庫隶糕,就不適用瓷产。另外,目前 Seata 的實現(xiàn)還存在一些局限枚驻,比如:事務(wù)隔離級別最高支持到?讀已提交?的水平濒旦,SQL 的解析還不能涵蓋全部的語法等。為了覆蓋 Fescar 原生機制暫時不能支持應(yīng)用場景再登,我們定義了另外一種工作模式尔邓。

?MT(Manual Transaction)模式

這種模式下,分支事務(wù)需要應(yīng)用自己來定義業(yè)務(wù)本身及提交和回滾的邏輯锉矢。MT 模式一方面是 AT 模式的補充梯嗽。另外,更重要的價值在于沽损,通過 MT 模式可以把眾多非事務(wù)性資源納入全局事務(wù)的管理中灯节。AT 和 MT 模式的分支從根本上行為模式是一致的,所以可以完全兼容绵估,即显晶,一個全局事務(wù)中,可以同時存在 AT 和 MT 的分支壹士。這樣就可以達到全面覆蓋業(yè)務(wù)場景的目的:AT 模式可以支持的,使用 AT 模式偿警;AT 模式暫時支持不了的躏救,用 MT 模式來替代。另外螟蒸,自然的盒使,MT 模式管理的非事務(wù)性資源也可以和支持事務(wù)的關(guān)系型數(shù)據(jù)庫資源一起,納入同一個分布式事務(wù)的管理中七嫌。

4少办、具體處理流程

分別描述了insert/delete/update操作、讀已提交操作诵原、提交操作和回滾操作等四個操作的序列圖(一種可能的實現(xiàn)方式)英妓。

1)insert/delete/update操作流程序列圖

2)讀已提交操作流程序列圖

3)提交操作流程序列圖

4)回滾操作流程序列圖

五挽放、開源軟件ServiceComb Pack

1、簡介

????????ServiceComb是華為云于2017年6月開源的微服務(wù)框架蔓纠,并于2017年12月正式進入Apache軟件基金會孵化辑畦。其包括一站式的服務(wù)注冊、服務(wù)治理腿倚、動態(tài)配置功能纯出,具備服務(wù)化契約增強、多語言SDK支持敷燎、多通信協(xié)議支持等優(yōu)勢特性, 并提供SAGA數(shù)據(jù)最終一致性方案解決微服務(wù)架構(gòu)數(shù)據(jù)一致性難題暂筝。ServiceComb 兼容Spring Cloud等業(yè)界流行微服務(wù)框架,互通業(yè)界生態(tài)硬贯。

????????ServiceComb Saga是針對微服務(wù)分布式事務(wù)最終一致性問題提供的解決方案焕襟。Saga分布式事務(wù)是由多個相關(guān)聯(lián)的的本地事務(wù)操作所組成。Saga協(xié)調(diào)器負責(zé)保證Saga事務(wù)的最終一致性澄成。當(dāng)本地事務(wù)執(zhí)行出錯時胧洒,Saga協(xié)調(diào)器會自動執(zhí)行相關(guān)的恢復(fù)操作保證分布式事務(wù)的最終一致性。相比其它的分布式事務(wù)一致性方案墨状,Saga在簡化事務(wù)配置以及提供多種事務(wù)恢復(fù)機制上有很明顯的優(yōu)勢卫漫。目前開發(fā)的ServiceComb Saga 0.1.0支持用戶通過Annoation的方式定義事務(wù)操作以及撤銷事務(wù)操作的服務(wù)接口, 同時Saga協(xié)調(diào)器監(jiān)控追蹤事務(wù)的執(zhí)行情況并負責(zé)協(xié)調(diào)事務(wù)執(zhí)行者肾砂,保證事務(wù)的最終一致性列赎。

2、架構(gòu)

????????Pack中包含兩個組件镐确,即?alpha?和?omega趣倾。

????????alpha充當(dāng)協(xié)調(diào)者的角色,主要負責(zé)對事務(wù)的事件進行持久化存儲以及協(xié)調(diào)子事務(wù)的狀態(tài)身腻,使其得以最終與全局事務(wù)的狀態(tài)保持一致驱犹。????????

????????omega是微服務(wù)中內(nèi)嵌的一個agent,負責(zé)對網(wǎng)絡(luò)請求進行攔截并向alpha上報事務(wù)事件息堂,并在異常情況下根據(jù)alpha下發(fā)的指令執(zhí)行相應(yīng)的補償操作嚷狞。

3、Omega內(nèi)部運行機制

????????omega是微服務(wù)中內(nèi)嵌的一個agent床未。當(dāng)服務(wù)收到請求時振坚,omega會將其攔截并從中提取請求信息中的全局事務(wù)id作為其自身的全局事務(wù)id(即Saga事件id),并提取本地事務(wù)id作為其父事務(wù)id渡八。在預(yù)處理階段啃洋,alpha會記錄事務(wù)開始的事件;在后處理階段损离,alpha會記錄事務(wù)結(jié)束的事件。因此绝编,每個成功的子事務(wù)都有一一對應(yīng)的開始及結(jié)束事件僻澎。

4窟勃、服務(wù)間通信流程

????????服務(wù)間通信的流程與Zipkin的類似逗堵。在服務(wù)生產(chǎn)方蜒秤,omega會攔截請求中事務(wù)相關(guān)的id來提取事務(wù)的上下文。在服務(wù)消費方作媚,omega會在請求中注入事務(wù)相關(guān)的id來傳遞事務(wù)的上下文纸泡。通過服務(wù)提供方和服務(wù)消費方的這種協(xié)作處理,子事務(wù)能連接起來形成一個完整的全局事務(wù)蚤假。

5磷仰、Saga具體處理流程

????????Saga處理場景是要求相關(guān)的子事務(wù)提供事務(wù)處理函數(shù)同時也提供補償函數(shù)芒划。Saga協(xié)調(diào)器alpha會根據(jù)事務(wù)的執(zhí)行情況向omega發(fā)送相關(guān)的指令欧穴,確定是否向前重試或者向后恢復(fù)泵殴。

1)成功場景

成功場景下笑诅,每個事務(wù)都會有開始和有對應(yīng)的結(jié)束事件疮鲫。

2)異常場景

????????異常場景下俊犯,omega會向alpha上報中斷事件伤哺,然后alpha會向該全局事務(wù)的其它已完成的子事務(wù)發(fā)送補償指令立莉,確保最終所有的子事務(wù)要么都成功,要么都回滾茫舶。

3)超時場景 (需要調(diào)整)

????????超時場景下饶氏,已超時的事件會被alpha的定期掃描器檢測出來有勾,與此同時柠衅,該超時事務(wù)對應(yīng)的全局事務(wù)也會被中斷。

6贷祈、TCC具體處理流程

????????TCC(try-confirm-cancel)與Saga事務(wù)處理方式相比多了一個Try方法势誊。事務(wù)調(diào)用的發(fā)起方來根據(jù)事務(wù)的執(zhí)行情況協(xié)調(diào)相關(guān)各方進行提交事務(wù)或者回滾事務(wù)粟耻。

1)成功場景

成功場景下眉踱, 每個事務(wù)都會有開始和對應(yīng)的結(jié)束事件谈喳。

2)異常場景

????????異常場景下,事務(wù)發(fā)起方會向alpha上報異常事件赏僧,然后alpha會向該全局事務(wù)的其它已完成的子事務(wù)發(fā)送補償指令淀零,確保最終所有的子事務(wù)要么都成功,要么都回滾驾中。

六哀卫、Seata和ServiceComb Pack對比

1此改、出身

????????Seata是阿里巴巴開源的分布式事務(wù)中間件,基于其內(nèi)部的TXC和GTS的技術(shù)積累占调。雖然此框架非骋萍簦活躍纵苛,但是19年剛剛開源,用于生產(chǎn)環(huán)境風(fēng)險較大取试。

????????servicecomb-pack出自華為微服務(wù)框架servicecomb瞬浓,servicecomb在Apache已經(jīng)畢業(yè)了蓬坡,但是一直比較“低調(diào)”屑咳。知名數(shù)據(jù)庫中間Sharding-Sphere采用的就是servicecomb-pack提供的saga方案。

2杖爽、實現(xiàn)原理

????????Seata實際上本質(zhì)就是將一個分布式事務(wù)轉(zhuǎn)化為多個單庫事務(wù)掂林。采用Saga的思想泻帮,所有的正向操作计寇,都保留逆向操作番宁。一旦要回滾,只需要執(zhí)行逆向操作就可以了踱蠢。在業(yè)務(wù)數(shù)據(jù)庫中額外增加一張事件表茎截,這個事件表就是關(guān)鍵所在赶盔,在更新正常業(yè)務(wù)數(shù)據(jù)庫的同時于未,在一個單庫事務(wù)內(nèi)(同一個數(shù)據(jù)庫連接)同步更新事件表,這樣來保證不丟數(shù)據(jù)抖坪。我們可以回顧一下一致性的要求柳击,“要么同時成功片习,要么同時失敗藕咏。”單庫事務(wù)就可以保證饥悴。

? ??????servicecomb-pack和Seata一樣西设,同樣是saga的思想,所有的正向操作棠笑,都保留逆向操作蓖救。一旦要回滾印屁,只需要執(zhí)行逆向操作就可以了雄人。但是柠衍,除此之外,servicecomb-pack也支持TCC牺勾。如圖所示驻民,Omega作為一個客戶端履怯,攔截所有的事務(wù)操作叹洲,事務(wù)開始向Alpha記錄開始記錄,事務(wù)結(jié)束向Alpha記錄事務(wù)結(jié)束記錄蝗柔,一旦出現(xiàn)問題癣丧,直接在Alpha事件表中生成逆向操作胁编,你應(yīng)該已經(jīng)看出來了,和fescar不同的是早直,事件表中的數(shù)據(jù)存儲在全局協(xié)調(diào)者(alpha)這一側(cè)莽鸿。

????????兩種做法各有優(yōu)劣吧拾给,存在業(yè)務(wù)側(cè)實際上是有侵入的蒋得,不是絕對意義上的無侵入额衙,雖然單庫事務(wù)性能不錯怕吴,但是事件表的所有操作都會影響正常業(yè)務(wù)转绷,無法做到更好的隔離性议经。存在協(xié)調(diào)者一側(cè)相對來說隔離性更好一些,但是這里會有概率產(chǎn)生不一致咧织,例如习绢,實際上業(yè)務(wù)操作已經(jīng)完成了闪萄,數(shù)據(jù)庫更新成功了耸黑,但是寫事件日志可能會失敗大刊,這時候協(xié)調(diào)者會認為業(yè)務(wù)操作也失敗了。

3搜锰、其它對比

穩(wěn)定性:servicecomb-pack略勝一籌耿战。更早的項目剂陡。

隔離性:Seata寫隔離通過TC提供的分布式鎖來實現(xiàn),讀隔離通過select for update實現(xiàn)歌馍,當(dāng)然松却,servicecomb-pack同樣可以通過select for update實現(xiàn)讀隔離晓锻。

復(fù)雜度:servicecomb-pack略勝一籌飞几。角色少屑墨,思路簡單绪钥。業(yè)務(wù)側(cè)程腹,兩個框架都可以通過簡單的注解實現(xiàn)。

文檔:fescar略勝一籌色鸳。

性能:沒有實際測試,從原理上來講吏砂,相差無幾狐血。

支持的數(shù)據(jù)庫:fescar目前只支持mysql,servicecomb-pack的方案不區(qū)分數(shù)據(jù)庫浪默。

4纳决、總結(jié)

????????雖然兩個框架的目標都是讓業(yè)務(wù)開發(fā)人員更簡單岳链,不用關(guān)心分布式事務(wù)的問題劲件,但是在我看來零远,如果要使用牵辣,還是要搞清楚原理纬向,除非對此問題非常敏感戴卜,否則投剥,應(yīng)該謹慎使用江锨,能不用最好不用啄育。 兩個框架都在快速發(fā)展中挑豌,從實現(xiàn)思想上來講非常相似墩崩,都是很好的解決方案泰鸡,未來的情況主要看投入程度盛龄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末余舶,一起剝皮案震驚了整個濱河市匿值,隨后出現(xiàn)的幾起案子挟憔,更是在濱河造成了極大的恐慌绊谭,老刑警劉巖汪拥,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宪赶,死亡現(xiàn)場離奇詭異搂妻,居然都是意外死亡辕棚,警方通過查閱死者的電腦和手機坟募,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門懈糯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赚哗,“玉大人,你說我怎么就攤上這事渐逃∏丫眨” “怎么了面殖?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵脊僚,是天一觀的道長辽幌。 經(jīng)常有香客問我乌企,道長,這世上最難降的妖魔是什么梁剔? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任荣病,我火速辦了婚禮个盆,結(jié)果婚禮上颊亮,老公的妹妹穿的比我還像新娘终惑。我一直安慰自己门扇,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著适揉,像睡著了一般临梗。 火紅的嫁衣襯著肌膚如雪盟庞。 梳的紋絲不亂的頭發(fā)上什猖,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天降铸,我揣著相機與錄音摇零,去河邊找鬼推掸。 笑死,一個胖子當(dāng)著我的面吹牛驻仅,可吹牛的內(nèi)容都是我干的谅畅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼噪服,長吁一口氣:“原來是場噩夢啊……” “哼毡泻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起仇味,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎雹顺,沒想到半個月后丹墨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡嬉愧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年带到,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡揽惹,死狀恐怖被饿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情搪搏,我是刑警寧澤狭握,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站疯溺,受9級特大地震影響论颅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜囱嫩,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一恃疯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墨闲,春花似錦今妄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至瞻离,卻和暖如春腾仅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背套利。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工推励, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肉迫。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓验辞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親昂拂。 傳聞我的和親對象是個殘疾皇子受神,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容