分布式原理-分布式事務

前言

事務是包含一系列操作的一個有邊界的工作序列,有明確的開始和結(jié)束標志烂翰,并且要具備原子性夯缺,要么被完全執(zhí)行蚤氏,要么完全失敗甘耿。因此系統(tǒng)做了微服務拆分以后,面臨的最大的問題就是如何保證事務的一致性竿滨,原先的事務在一個進程中只要保證單進程中的事務性就可以佳恬,服務拆分做了分布式以后,就面臨著一個事務涉及到多應用節(jié)點之間如何保證事務的ACID于游。分布式事務毁葱,就是在分布式系統(tǒng)中運行的事務,由多個本地事務組合而成贰剥。

分布式事務主要是解決在分布式環(huán)境下倾剿,組合事務的一致性問題。實現(xiàn)分布式事務有以下 3 種基本方法:

  • 基于 XA 協(xié)議的二階段提交協(xié)議方法;

  • 三階段提交協(xié)議方法前痘;

  • 基于消息的最終一致性方法凛捏。

其中,基于 XA 協(xié)議的二階段提交協(xié)議方法和三階段提交協(xié)議方法芹缔,采用了強一致性,遵從 ACID,基于消息的最終一致性方法钱床,采用了最終一致性积担,遵從 BASE 理論。

XA二階段提交

XA 是一個分布式事務協(xié)議芝硬,規(guī)定了事務管理器和資源管理器接口蚜点。因此,XA 協(xié)議可以分為兩部分拌阴,即事務管理器和本地資源管理器禽额。為了保證它們的一致性,我們需要引入一個協(xié)調(diào)者來管理所有的節(jié)點皮官,并確保這些節(jié)點正確提交操作結(jié)果脯倒,若提交失敗則放棄事務。

兩階段提交協(xié)議的執(zhí)行過程捺氢,分為投票(voting)和提交(commit)兩個階段:

1)投票為第一階段藻丢,協(xié)調(diào)者(Coordinator,即事務管理器)會向事務的參與者(Cohort摄乒,即本地資源管理器)發(fā)起執(zhí)行操作的 CanCommit 請求悠反,并等待參與者的響應。參與者接收到請求后馍佑,會執(zhí)行請求中的事務操作斋否,記錄日志信息但不提交,待參與者執(zhí)行成功拭荤,則向協(xié)調(diào)者發(fā)送“Yes”消息茵臭,表示同意操作;若不成功舅世,則發(fā)送“No”消息旦委,表示終止操作。

2)當所有的參與者都返回了操作結(jié)果(Yes 或 No 消息)后雏亚,系統(tǒng)進入了提交階段缨硝。在提交階段,協(xié)調(diào)者會根據(jù)所有參與者返回的信息向參與者發(fā)送 DoCommit 或 DoAbort 指令:

  • 若協(xié)調(diào)者收到的都是“Yes”消息罢低,則向參與者發(fā)送“DoCommit”消息查辩,參與者會完成剩余的操作并釋放資源,然后向協(xié)調(diào)者返回“HaveCommitted”消息;

  • 如果協(xié)調(diào)者收到的消息中包含“No”消息宜岛,則向所有參與者發(fā)送“DoAbort”消息匀钧,此時發(fā)送“Yes”的參與者則會根據(jù)之前執(zhí)行操作時的回滾日志對操作進行回滾,然后所有參與者會向協(xié)調(diào)者發(fā)送“HaveCommitted”消息谬返;

  • 協(xié)調(diào)者接收到“HaveCommitted”消息之斯,就意味著整個事務結(jié)束了。

下面舉個兩階段提交的例子:

兩階段提交

1)第一階段:訂單系統(tǒng)中將與用戶 A 有關的訂單數(shù)據(jù)庫鎖住遣铝,準備好增加一條關于用戶 A 購
買 10套口罩的信息佑刷,并將同意消息“Yes”回復給協(xié)調(diào)者。而庫存系統(tǒng)由于 口罩庫存不
足酿炸,出貨失敗瘫絮,因此向協(xié)調(diào)者回復了一個終止消息“No”。

2)第二階段:由于庫存系統(tǒng)操作不成功填硕,因此麦萤,協(xié)調(diào)者就會向訂單系統(tǒng)和庫存系統(tǒng)發(fā)送“DoAbort”消息。訂單系統(tǒng)接收到“DoAbort”消息后扁眯,將系統(tǒng)內(nèi)的數(shù)據(jù)退回到?jīng)]有用戶 A 購買 10套口罩的版本壮莹,并釋放鎖住的數(shù)據(jù)庫資源。訂單系統(tǒng)和庫存系統(tǒng)完成操作
后姻檀,向協(xié)調(diào)者發(fā)送“HaveCommitted”消息命满,表示完成了事務的撤銷操作。

兩階段提交的問題主要有下面幾種:

  • 同步阻塞問題:二階段提交算法在執(zhí)行過程中绣版,所有參與節(jié)點都是事務阻塞型的胶台。也就是說,當本地資源管理器占有臨界資源時杂抽,其他資源管理器如果要訪問同一臨界資源诈唬,會處于阻塞狀態(tài)。
  • 單點故障問題:基于 XA 的二階段提交算法類似于集中式算法缩麸,一旦事務管理器發(fā)生故障铸磅,整個系統(tǒng)都處于停滯狀態(tài)。尤其是在提交階段匙睹,一旦事務管理器發(fā)生故障愚屁,資源管理器會由于等待管理器的消息,而一直鎖定事務資源痕檬,導致整個系統(tǒng)被阻塞。
  • 數(shù)據(jù)不一致問題:在提交階段送浊,當協(xié)調(diào)者向參與者發(fā)送 DoCommit 請求之后梦谜,如果發(fā)生了局部網(wǎng)絡異常,或者在發(fā)送提交請求的過程中協(xié)調(diào)者發(fā)生了故障,就會導致只有一部分參與者接收到了提交請求并執(zhí)行提交操作唁桩,但其他未接到提交請求的那部分參與者則無法執(zhí)行事務提交闭树。于是整個分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)不一致的問題。

三階段提交

三階段提交協(xié)議(Three-phase commit protocol荒澡,3PC)报辱,是對二階段提交(2PC)的改進。為了解決兩階段提交的同步阻塞和數(shù)據(jù)不一致問題单山,三階段提交引入了超時機制和準備階段碍现。同時在協(xié)調(diào)者和參與者中引入超時機制。如果協(xié)調(diào)者或參與者在規(guī)定的時間內(nèi)沒有接收到來自其他節(jié)點的響應米奸,就會根據(jù)當前的狀態(tài)選擇提交或者終止整個事務昼接。

在第一階段和第二階段中間引入了一個準備階段,也就是在提交階段之前悴晰,加入了一個預提交階段慢睡。在預提交階段排除一些不一致的情況,保證在最后提交之前各參與節(jié)點的狀態(tài)是一致的铡溪。3PC 把 2PC 的提交階段一分為二漂辐,這樣三階段提交協(xié)議就有 CanCommit、PreCommit棕硫、DoCommit 三個階段者吁。

三階段提交:
1)CanCommit階段:協(xié)調(diào)者向參與者發(fā)送請求操作(CanCommit請求),詢問參與者是否可以執(zhí)行事務提交操作饲帅,然后等待參與者的響應复凳;參與者收到CanCommit 請求之后,回復 Yes灶泵,表示可以順利執(zhí)行事務育八;否則回復 No。
2)PreCommit階段:協(xié)調(diào)者根據(jù)參與者的回復情況赦邻,來決定是否可以進行 PreCommit 操作髓棋,如果所有參與者都回復Yes,則所有參與者執(zhí)行PreCommit惶洲,并將Undo 和 Redo信息記錄到事務日志中按声,返回協(xié)調(diào)者ACK。假如任何一個參與者向協(xié)調(diào)者發(fā)送了“No”消息恬吕,或者等待超時之后签则,協(xié)調(diào)者都沒有收到參與者的響應,就執(zhí)行中斷事務的操作铐料。
3)DoCommit階段:DoCmmit 階段進行真正的事務提交渐裂,根據(jù) PreCommit 階段協(xié)調(diào)者發(fā)送的消息豺旬,進入執(zhí)行提交階段或事務中斷階段。a.發(fā)送提交請求柒凉。協(xié)調(diào)者接收到所有參與者發(fā)送的 Ack 響應族阅,從預提交狀態(tài)進入到提交狀態(tài),并向所有參與者發(fā)送 DoCommit 消息膝捞。b.發(fā)送中斷請求坦刀。協(xié)調(diào)者向所有參與者發(fā)送 Abort 請求。事務回滾蔬咬。參與者接收到 Abort 消息之后鲤遥,利用其在 PreCommit 階段記錄的 Undo信息執(zhí)行事務的回滾操作,并釋放所有鎖住的資源计盒。

下面舉個三階段提交的例子:

第一階段:協(xié)調(diào)者發(fā)送給訂單系統(tǒng)canConfirm渴频?,訂單系統(tǒng)檢查資源可用北启。返回消息“Yes”回復給協(xié)調(diào)者卜朗。同時發(fā)送給庫存系統(tǒng)canConfirm?咕村,庫存系統(tǒng)檢查資源是否可用场钉,如果可用返回“Yes”。

CanConfirm階段

第二階段:檢查階段訂單系統(tǒng)和庫存系統(tǒng)都返回“Yes”懈涛,則同時發(fā)給訂單系統(tǒng)和庫存系統(tǒng)PreCommit請求逛万,訂單系統(tǒng)和庫存系統(tǒng)對資源進行鎖庫操作,將操作寫到Redo和Undo日志.最后返回ACK批钠。

PreConfirm階段

第三階段:如果收到訂單系統(tǒng)和庫存系統(tǒng)的PreConfirm階段的ACK后會最后向兩個系統(tǒng)發(fā)送DoCommit指令宇植,訂單系統(tǒng)和庫存系統(tǒng)進行實際操作,成功后返回ACK并釋放資源鎖埋心。
在默認情況下指郁,參與者會自動將超時的事務進行提交,不會像兩階段提交那樣被阻塞
住拷呆。

DoConfirm階段

基于消息的最終一致性

2PC 和 3PC 這兩種方法闲坎,有兩個共同的缺點,一是都需要鎖定資源茬斧,降低系統(tǒng)性能腰懂;二是,沒有解決數(shù)據(jù)不一致的問題项秉⌒辶铮基于分布式消息的最終一致性方案的事務處理,引入了一個消息中間件(MessageQueue伙狐,MQ)涮毫,用于在多個應用之間進行消息傳遞瞬欧。將需要分布式處理的事務通過消息或者日志的方式異步執(zhí)行贷屎,消息或日志可以存到本地文件罢防、數(shù)據(jù)庫或消息隊列中,再通過業(yè)務規(guī)則進行失敗重試唉侄。

下面舉個例子:

基于消息的最終一致性
  1. 訂單系統(tǒng)把訂單消息發(fā)給消息中間件咒吐,消息狀態(tài)標記為“待確認”。
  2. 消息中間件收到消息后属划,進行消息持久化操作恬叹,即在消息存儲系統(tǒng)中新增一條狀態(tài)為“待發(fā)送”的消息。
  3. 消息中間件返回消息持久化結(jié)果(成功 / 失斖小)绽昼,訂單系統(tǒng)根據(jù)返回結(jié)果判斷如何進行
    業(yè)務操作。失敗须蜗,放棄訂單硅确,結(jié)束(必要時向上層返回失敗結(jié)果);成功明肮,則創(chuàng)建訂單菱农。
  4. 訂單操作完成后,把操作結(jié)果(成功 / 失斒凉馈)發(fā)送給消息中間件循未。
  5. 消息中間件收到業(yè)務操作結(jié)果后,根據(jù)結(jié)果進行處理:失敗秫舌,刪除消息存儲中的消息的妖,結(jié)束;成功足陨,則更新消息存儲中的消息狀態(tài)為“待發(fā)送(可發(fā)送)”嫂粟,并執(zhí)行消息投遞。
  6. 如果消息狀態(tài)為“可發(fā)送”钠右,則 MQ 會將消息發(fā)送給支付系統(tǒng)赋元,表示已經(jīng)創(chuàng)建好訂單,需要對訂單進行支付飒房。支付系統(tǒng)也按照上述方式進行訂單支付操作搁凸。
  7. 訂單系統(tǒng)支付完成后,會將支付消息返回給消息中間件狠毯,中間件將消息傳送給訂單系統(tǒng)护糖。訂單系統(tǒng)再調(diào)用庫存系統(tǒng),進行出貨操作嚼松。

總結(jié)

XA二階段提交協(xié)議 三階段提交協(xié)議 基于分布式消息的最終一致性方案
算法一致性類別 強一致性 強一致性 最終一致性
執(zhí)行方式 同步執(zhí)行 同步執(zhí)行 異步執(zhí)行
同步阻塞問題
單點故障問題
系統(tǒng)并發(fā)度 XA二階段提交<三階段提交<分布式消息最終一致性
分布式事務性能 XA二階段提交<三階段提交<分布式消息最終一致性
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嫡良,一起剝皮案震驚了整個濱河市锰扶,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寝受,老刑警劉巖坷牛,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異很澄,居然都是意外死亡京闰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門甩苛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹂楣,“玉大人,你說我怎么就攤上這事讯蒲∪粒” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵墨林,是天一觀的道長赁酝。 經(jīng)常有香客問我,道長萌丈,這世上最難降的妖魔是什么赞哗? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮辆雾,結(jié)果婚禮上肪笋,老公的妹妹穿的比我還像新娘。我一直安慰自己度迂,他們只是感情好藤乙,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惭墓,像睡著了一般坛梁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上腊凶,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天划咐,我揣著相機與錄音,去河邊找鬼钧萍。 笑死褐缠,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的风瘦。 我是一名探鬼主播队魏,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼万搔!你這毒婦竟也來了胡桨?” 一聲冷哼從身側(cè)響起官帘,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎昧谊,沒想到半個月后刽虹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡揽浙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年状婶,在試婚紗的時候發(fā)現(xiàn)自己被綠了意敛。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馅巷。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖草姻,靈堂內(nèi)的尸體忽然破棺而出钓猬,到底是詐尸還是另有隱情,我是刑警寧澤撩独,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布敞曹,位于F島的核電站,受9級特大地震影響综膀,放射性物質(zhì)發(fā)生泄漏澳迫。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一剧劝、第九天 我趴在偏房一處隱蔽的房頂上張望橄登。 院中可真熱鬧,春花似錦讥此、人聲如沸拢锹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽卒稳。三九已至,卻和暖如春他巨,著一層夾襖步出監(jiān)牢的瞬間充坑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工捻爷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人觉痛。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓役衡,卻偏偏與公主長得像,于是被迫代替她去往敵國和親薪棒。 傳聞我的和親對象是個殘疾皇子手蝎,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355