分布式事務

本質(zhì)上來說,分布式事務就是為了保證不同數(shù)據(jù)庫的數(shù)據(jù)一致性。

1. 分布式理論

1.1. CAP定律

CAP指的是:一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition tolerance)。

CAP定律說的是,在一個分布式系統(tǒng)中,最多只能滿足C、A、P中的兩個,不可能三個同時滿足。

在分布式系統(tǒng)中,網(wǎng)絡無法 100% 可靠,分區(qū)其實是一個必然現(xiàn)象。如果我們選擇了 CA 而放棄了 P,那么當發(fā)生分區(qū)現(xiàn)象時,為了保證一致性,這個時候必須拒絕請求,但是 A 又不允許,所以分布式系統(tǒng)理論上不可能選擇 CA 架構(gòu),只能選擇 CP 或者 AP 架構(gòu)。

而且,顯然,任何橫向擴展策略都要依賴于數(shù)據(jù)分區(qū)。因此,設(shè)計人員必須在一致性與可用性之間做出選擇。

1.2. BASE理論

往往在分布式系統(tǒng)中無法實現(xiàn)完全一致性,于是有了BASE理論,它是對CAP定律的進一步擴充

BASE指的是:

Basically Available(基本可用)?: 分布式系統(tǒng)在出現(xiàn)故障時,允許損失部分可用功能,保證核心功能可用

Soft state(軟狀態(tài))?: 允許系統(tǒng)中存在中間狀態(tài),這個狀態(tài)不影響系統(tǒng)可用性

Eventually consistent(最終一致性)?: 經(jīng)過一段時間后,所有節(jié)點數(shù)據(jù)都將會達到一致

BASE理論是對CAP中的一致性和可用性進行一個權(quán)衡的結(jié)果

BASE理論核心思想就是:我們無法做到強一致,但每個應用都可以根據(jù)自身的業(yè)務特點,采用適當?shù)姆绞絹硎瓜到y(tǒng)達到最終一致性

BASE理論是通過犧牲強一致性來獲得可用性,并允許數(shù)據(jù)在一段時間內(nèi)是不一致的,但最終達到一致狀態(tài)

2. 分布式事務解決方案

2.1. 基于XA協(xié)議的兩階段提交

XA協(xié)議包含兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由數(shù)據(jù)庫實現(xiàn),目前主流的關(guān)系型數(shù)據(jù)庫都實現(xiàn)了XA接口,而事務管理器作為全局的調(diào)度者,負責各個本地資源的提交和回滾。

優(yōu)點:盡量保證了數(shù)據(jù)的強一致,適合對數(shù)據(jù)強一致要求很高的關(guān)鍵領(lǐng)域。(其實也不能100%保證強一致)

缺點:XA協(xié)議遵循強一致性。在事務執(zhí)行過程中,各個節(jié)點占用著數(shù)據(jù)庫資源,只有當所有節(jié)點準備完畢,事務協(xié)調(diào)者才會通知提交,參與者提交后釋放資源。這樣的過程有著非常明顯的性能問題。

(PS:XA三階段提交在兩階段提交的基礎(chǔ)上增加了CanCommit階段,并且引入了超時機制。這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段。)

兩階段提交方案鎖定資源時間長,對性能影響很大,基本不適合解決微服務事務問題。

2.2. TCC方案

TCC 其實就是采用的補償機制,其核心思想是:針對每個操作,都要注冊一個與其對應的確認和補償(撤銷)操作。

將整個業(yè)務邏輯的每個分支顯式的分成了Try、Confirm、Cancel三個操作。Try部分完成業(yè)務的準備工作,confirm部分完成業(yè)務的提交,cancel部分完成事務的回滾。

拿前面的下單的例子來說,服務A的try相當于查詢是否有可用的積分,Confirm相當于扣減積分,Cancel相當于增加積分。

優(yōu)點:跟2PC比起來,實現(xiàn)以及流程相對簡單了一些,但數(shù)據(jù)的一致性比2PC也要差一些

缺點:TCC屬于應用層的一種補償方式,所以需要程序員在實現(xiàn)的時候多寫很多補償?shù)拇a,而且補償?shù)臅r候也有可能失敗,在一些場景中,一些業(yè)務流程可能用TCC不太好定義及處理。

2.3. 本地消息表

其基本的設(shè)計思想是將遠程分布式事務拆分成一系列的本地事務。

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

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

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

本地消息表是一個比較好的做法,這樣可以有效防止重復消息處理

以轉(zhuǎn)賬為例,這種方式的過程是這樣的:

當A想給B轉(zhuǎn)100元時,A賬戶先減100元,然后在其本地消息表中加一條記錄,寫明A給B轉(zhuǎn)100元,并且狀態(tài)是消息未發(fā)送。這個向消息表寫數(shù)據(jù)的操作和A賬戶扣減100元在同一個事務中,依靠數(shù)據(jù)庫本地事務保證一致性,即只要A減100成功了,這條記錄必然成功。

定時任務去輪詢消息表,把沒有發(fā)出去的消息都發(fā)出去,并標記狀態(tài)為已發(fā)送

B收到這個消息的時候先存入本地的消息表,標記未處理

B這邊定時掃描未處理的消息,處理完成后更新狀態(tài)為已處理

有了消息表以后,可以防止重復、可以重試、保證消息不丟失、做冪等性校驗

優(yōu)點一種非常經(jīng)典的實現(xiàn),避免了分布式事務,實現(xiàn)了最終一致性。

缺點:消息表會耦合到業(yè)務系統(tǒng)中,如果沒有封裝好的解決方案,會有很多雜活需要處理。

2.4. MQ(非事務消息)

如果不把本地數(shù)據(jù)庫操作和消息投遞放在同一個事務中,那么很難保證本地事務成功后消息一定發(fā)送成功

如果把它們放在同一個事務中,那么考慮下面幾種情況:

第1種情況:本地數(shù)據(jù)庫操作成功,消息發(fā)送成功,皆大歡喜

第2種情況:本地數(shù)據(jù)庫操作失敗,消息不會發(fā)送

第3種情況:本地數(shù)據(jù)庫操作成功,消息發(fā)送失?。⊕伄惓#?,事務回滾

以上三種情況都是正常的,不會有什么問題

然而,考慮下面這種情況:

本地數(shù)據(jù)庫操作成功,消息投遞成功,應用服務器掛了,事務回滾,于是不一致出現(xiàn)了,即本地數(shù)據(jù)庫操作沒成功,而消息卻發(fā)成功了

如果這是轉(zhuǎn)賬的話,對方會無緣無故多出一筆錢

究其原因,是因為發(fā)消息不是數(shù)據(jù)庫操作,它不受ACID的限制,也就是說數(shù)據(jù)庫事務管不了發(fā)消息,因為他們不是同一個數(shù)據(jù)庫的同一個事務,當然還有一個原因是發(fā)出去的消息是無法撤銷的。(PS:在后面將要介紹的RocketMQ的事務消息可以撤銷)

而上面消息表的話,是同一個數(shù)據(jù)庫的同一個事務,因此不會出現(xiàn)這種問題

綜上,這種方式有一定的風險,它無法保證本地數(shù)據(jù)庫操作 與 消息投遞的一致性,不建議使用

2.5. MQ(事務消息)

目前,僅阿里云的RocketMQ支持事務消息。幫助用戶實現(xiàn)類似 X/Open XA 的分布事務功能,通過 MQ 事務消息能達到分布式事務的最終一致。

說明:

發(fā)送方向 MQ 服務端發(fā)送消息

MQ Server 將消息持久化成功之后,向發(fā)送方 ACK 確認消息已經(jīng)發(fā)送成功,此時消息為半消息

發(fā)送方開始執(zhí)行本地事務邏輯

發(fā)送方根據(jù)本地事務執(zhí)行結(jié)果向 MQ Server 提交二次確認(Commit 或是 Rollback),MQ Server 收到 Commit 狀態(tài)則將半消息標記為可投遞,訂閱方最終將收到該消息;MQ Server 收到 Rollback 狀態(tài)則刪除半消息,訂閱方將不會接受該消息

在斷網(wǎng)或者是應用重啟的特殊情況下,上述步驟4提交的二次確認最終未到達 MQ Server,經(jīng)過固定時間后 MQ Server 將對該消息發(fā)起消息回查

發(fā)送方收到消息回查后,需要檢查對應消息的本地事務執(zhí)行的最終結(jié)果

發(fā)送方根據(jù)檢查得到的本地事務的最終狀態(tài)再次提交二次確認,MQ Server 仍按照步驟4對半消息進行操作

其中,事務消息發(fā)送對應步驟1、2、3、4,事務消息回查對應步驟5、6、7

2.6. GTS

全局事務服務(Global Transaction Service,簡稱 GTS)是一款高性能、高可靠、接入簡單的分布式事務中間件,用于解決分布式環(huán)境下的數(shù)據(jù)一致性問題。GTS 可以保證分布式系統(tǒng)中的分布式事務的 ACID 特性。它是阿里云的一款產(chǎn)品。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容