分布式事務是什么意思

本篇內(nèi)容主要講解“分布式事務是什么意思”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“分布式事務是什么意思”吧!

成都創(chuàng)新互聯(lián)公司主要從事網(wǎng)站設計制作、網(wǎng)站設計、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務松桃,10余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:13518219792

收藏 | 第一次有人把“分布式事務”講的這么簡單明了

不知道你是否遇到過這樣的情況,去小賣鋪買東西,付了錢,但是店主因為處理了一些其他事,居然忘記你付了錢,又叫你重新付。

又或者在網(wǎng)上購物明明已經(jīng)扣款,但是卻告訴我沒有發(fā)生交易。這一系列情況都是因為沒有事務導致的。這說明了事務在生活中的一些重要性。

有了事務,你去小賣鋪買東西,那就是一手交錢一手交貨。有了事務,你去網(wǎng)上購物,扣款即產(chǎn)生訂單交易。

事務的具體定義

事務提供一種機制將一個活動涉及的所有操作納入到一個不可分割的執(zhí)行單元,組成事務的所有操作只有在所有操作均能正常執(zhí)行的情況下方能提交,只要其中任一操作執(zhí)行失敗,都將導致整個事務的回滾。

簡單地說,事務提供一種“要么什么都不做,要么做全套(All or Nothing)”機制。

數(shù)據(jù)庫本地事務

ACID

說到數(shù)據(jù)庫事務就不得不說,數(shù)據(jù)庫事務中的四大特性 ACID:

A:原子性(Atomicity),一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環(huán)節(jié)。

事務在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務開始前的狀態(tài),就像這個事務從來沒有執(zhí)行過一樣。

就像你買東西要么交錢收貨一起都執(zhí)行,要么發(fā)不出貨,就退錢。

C:一致性(Consistency),事務的一致性指的是在一個事務執(zhí)行之前和執(zhí)行之后數(shù)據(jù)庫都必須處于一致性狀態(tài)。

如果事務成功地完成,那么系統(tǒng)中所有變化將正確地應用,系統(tǒng)處于有效狀態(tài)。

如果在事務中出現(xiàn)錯誤,那么系統(tǒng)中的所有變化將自動地回滾,系統(tǒng)返回到原始狀態(tài)。

I:隔離性(Isolation),指的是在并發(fā)環(huán)境中,當不同的事務同時操縱相同的數(shù)據(jù)時,每個事務都有各自的完整數(shù)據(jù)空間。

由并發(fā)事務所做的修改必須與任何其他并發(fā)事務所做的修改隔離。事務查看數(shù)據(jù)更新時,數(shù)據(jù)所處的狀態(tài)要么是另一事務修改它之前的狀態(tài),要么是另一事務修改它之后的狀態(tài),事務不會查看到中間狀態(tài)的數(shù)據(jù)。

打個比方,你買東西這個事情,是不影響其他人的。

D:持久性(Durability),指的是只要事務成功結束,它對數(shù)據(jù)庫所做的更新就必須***保存下來。

即使發(fā)生系統(tǒng)崩潰,重新啟動數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)庫還能恢復到事務成功結束時的狀態(tài)。

打個比方,你買東西的時候需要記錄在賬本上,即使老板忘記了那也有據(jù)可查。

InnoDB 實現(xiàn)原理

InnoDB 是 MySQL 的一個存儲引擎,大部分人對 MySQL 都比較熟悉,這里簡單介紹一下數(shù)據(jù)庫事務實現(xiàn)的一些基本原理。

在本地事務中,服務和資源在事務的包裹下可以看做是一體的,如下圖:

我們的本地事務由資源管理器進行管理:

而事務的 ACID 是通過 InnoDB 日志和鎖來保證。事務的隔離性是通過數(shù)據(jù)庫鎖的機制實現(xiàn)的,持久性通過 Redo Log(重做日志)來實現(xiàn),原子性和一致性通過 Undo Log 來實現(xiàn)。

Undo Log 的原理很簡單,為了滿足事務的原子性,在操作任何數(shù)據(jù)之前,首先將數(shù)據(jù)備份到一個地方(這個存儲數(shù)據(jù)備份的地方稱為 Undo Log)。然后進行數(shù)據(jù)的修改。

如果出現(xiàn)了錯誤或者用戶執(zhí)行了 Rollback 語句,系統(tǒng)可以利用 Undo Log 中的備份將數(shù)據(jù)恢復到事務開始之前的狀態(tài)。

和 Undo Log 相反,Redo Log 記錄的是新數(shù)據(jù)的備份。在事務提交前,只要將 Redo Log 持久化即可,不需要將數(shù)據(jù)持久化。

當系統(tǒng)崩潰時,雖然數(shù)據(jù)沒有持久化,但是 Redo Log 已經(jīng)持久化。系統(tǒng)可以根據(jù) Redo Log 的內(nèi)容,將所有數(shù)據(jù)恢復到***的狀態(tài)。對具體實現(xiàn)過程有興趣的同學可以去自行搜索擴展。

分布式事務

什么是分布式事務

分布式事務指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點之上。

簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的服務器上,且屬于不同的應用,分布式事務需要保證這些小操作要么全部成功,要么全部失敗。

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

分布式事務產(chǎn)生的原因

從上面本地事務來看,我們可以分為兩塊:

  • Service 產(chǎn)生多個節(jié)點

  • Resource 產(chǎn)生多個節(jié)點

Service 多個節(jié)點

隨著互聯(lián)網(wǎng)快速發(fā)展,微服務,SOA 等服務架構模式正在被大規(guī)模的使用。

舉個簡單的例子,一個公司之內(nèi),用戶的資產(chǎn)可能分為好多個部分,比如余額,積分,優(yōu)惠券等等。

在公司內(nèi)部有可能積分功能由一個微服務團隊維護,優(yōu)惠券又是另外的團隊維護。

這樣的話就無法保證積分扣減了之后,優(yōu)惠券能否扣減成功。

Resource多個節(jié)點

同樣的,互聯(lián)網(wǎng)發(fā)展得太快了,我們的 MySQL 一般來說裝***的數(shù)據(jù)就得進行分庫分表。

對于一個支付寶的轉賬業(yè)務來說,你給朋友轉錢,有可能你的數(shù)據(jù)庫是在北京,而你的朋友的錢是存在上海,所以我們依然無法保證他們能同時成功。

分布式事務的基礎

從上面來看分布式事務是隨著互聯(lián)網(wǎng)高速發(fā)展應運而生的,這是一個必然。

我們之前說過數(shù)據(jù)庫的 ACID 四大特性,已經(jīng)無法滿足我們分布式事務,這個時候又有一些新的大佬提出一些新的理論。

CAP

CAP 定理,又被叫作布魯爾定理。對于設計分布式系統(tǒng)(不僅僅是分布式事務)的架構師來說,CAP 就是你的入門理論。

C (一致性):對某個指定的客戶端來說,讀操作能返回***的寫操作。

對于數(shù)據(jù)分布在不同節(jié)點上的數(shù)據(jù)來說,如果在某個節(jié)點更新了數(shù)據(jù),那么在其他節(jié)點如果都能讀取到這個***的數(shù)據(jù),那么就稱為強一致,如果有某個節(jié)點沒有讀取到,那就是分布式不一致。

A (可用性):非故障的節(jié)點在合理的時間內(nèi)返回合理的響應(不是錯誤和超時的響應)??捎眯缘膬蓚€關鍵一個是合理的時間,一個是合理的響應。

合理的時間指的是請求不能***被阻塞,應該在合理的時間給出返回。合理的響應指的是系統(tǒng)應該明確返回結果并且結果是正確的,這里的正確指的是比如應該返回 50,而不是返回 40。

P (分區(qū)容錯性):當出現(xiàn)網(wǎng)絡分區(qū)后,系統(tǒng)能夠繼續(xù)工作。打個比方,這里集群有多臺機器,有臺機器網(wǎng)絡出現(xiàn)了問題,但是這個集群仍然可以正常工作。

熟悉 CAP 的人都知道,三者不能共有,如果感興趣可以搜索 CAP 的證明,在分布式系統(tǒng)中,網(wǎng)絡無法 100% 可靠,分區(qū)其實是一個必然現(xiàn)象。

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

對于 CP 來說,放棄可用性,追求一致性和分區(qū)容錯性,我們的 ZooKeeper 其實就是追求的強一致。

對于 AP 來說,放棄一致性(這里說的一致性是強一致性),追求分區(qū)容錯性和可用性,這是很多分布式系統(tǒng)設計時的選擇,后面的 BASE 也是根據(jù) AP 來擴展。

順便一提,CAP 理論中是忽略網(wǎng)絡延遲,也就是當事務提交時,從節(jié)點 A 復制到節(jié)點 B 沒有延遲,但是在現(xiàn)實中這個是明顯不可能的,所以總會有一定的時間是不一致。

同時 CAP 中選擇兩個,比如你選擇了 CP,并不是叫你放棄 A。因為 P 出現(xiàn)的概率實在是太小了,大部分的時間你仍然需要保證 CA。

就算分區(qū)出現(xiàn)了你也要為后來的 A 做準備,比如通過一些日志的手段,是其他機器回復至可用。

BASE

BASE 是 Basically Available(基本可用)、Soft state(軟狀態(tài))和 Eventually consistent (最終一致性)三個短語的縮寫,是對 CAP 中 AP 的一個擴展。

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

軟狀態(tài):允許系統(tǒng)中存在中間狀態(tài),這個狀態(tài)不影響系統(tǒng)可用性,這里指的是 CAP 中的不一致。

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

BASE 解決了 CAP 中理論沒有網(wǎng)絡延遲,在 BASE 中用軟狀態(tài)和最終一致,保證了延遲后的一致性。

BASE 和 ACID 是相反的,它完全不同于 ACID 的強一致性模型,而是通過犧牲強一致性來獲得可用性,并允許數(shù)據(jù)在一段時間內(nèi)是不一致的,但最終達到一致狀態(tài)。

分布式事務解決方案

有了上面的理論基礎后,這里開始介紹幾種常見的分布式事務的解決方案。

是否真的要分布式事務

在說方案之前,首先你一定要明確你是否真的需要分布式事務?

上面說過出現(xiàn)分布式事務的兩個原因,其中有個原因是因為微服務過多。我見過太多團隊一個人維護幾個微服務,太多團隊過度設計,搞得所有人疲勞不堪。

而微服務過多就會引出分布式事務,這個時候我不會建議你去采用下面任何一種方案,而是請把需要事務的微服務聚合成一個單機服務,使用數(shù)據(jù)庫的本地事務。

因為不論任何一種方案都會增加你系統(tǒng)的復雜度,這樣的成本實在是太高了,千萬不要因為追求某些設計,而引入不必要的成本和復雜度。

如果你確定需要引入分布式事務可以看看下面幾種常見的方案。

2PC

說到 2PC 就不得不聊數(shù)據(jù)庫分布式事務中的 XA Transactions。

在 XA 協(xié)議中分為兩階段:

  • 事務管理器要求每個涉及到事務的數(shù)據(jù)庫預提交(precommit)此操作,并反映是否可以提交。

  • 事務協(xié)調(diào)器要求每個數(shù)據(jù)庫提交數(shù)據(jù),或者回滾數(shù)據(jù)。

優(yōu)點:

  • 盡量保證了數(shù)據(jù)的強一致,實現(xiàn)成本較低,在各大主流數(shù)據(jù)庫都有自己實現(xiàn),對于 MySQL 是從 5.5 開始支持。

缺點:

  • 單點問題:事務管理器在整個流程中扮演的角色很關鍵,如果其宕機,比如在***階段已經(jīng)完成,在第二階段正準備提交的時候事務管理器宕機,資源管理器就會一直阻塞,導致數(shù)據(jù)庫無法使用。

  • 同步阻塞:在準備就緒之后,資源管理器中的資源一直處于阻塞,直到提交完成,釋放資源。

  • 數(shù)據(jù)不一致:兩階段提交協(xié)議雖然為分布式數(shù)據(jù)強一致性所設計,但仍然存在數(shù)據(jù)不一致性的可能。

比如在第二階段中,假設協(xié)調(diào)者發(fā)出了事務 Commit 的通知,但是因為網(wǎng)絡問題該通知僅被一部分參與者所收到并執(zhí)行了 Commit 操作,其余的參與者則因為沒有收到通知一直處于阻塞狀態(tài),這時候就產(chǎn)生了數(shù)據(jù)的不一致性。

總的來說,XA 協(xié)議比較簡單,成本較低,但是其單點問題,以及不能支持高并發(fā)(由于同步阻塞)依然是其***的弱點。

TCC

關于 TCC(Try-Confirm-Cancel)的概念,最早是由 Pat Helland 于 2007 年發(fā)表的一篇名為《Life beyond Distributed Transactions:an Apostate’s Opinion》的論文提出。

TCC 事務機制相比于上面介紹的 XA,解決了如下幾個缺點:

  • 解決了協(xié)調(diào)者單點,由主業(yè)務方發(fā)起并完成這個業(yè)務活動。業(yè)務活動管理器也變成多點,引入集群。

  • 同步阻塞:引入超時,超時后進行補償,并且不會鎖定整個資源,將資源轉換為業(yè)務邏輯形式,粒度變小。

  • 數(shù)據(jù)一致性,有了補償機制之后,由業(yè)務活動管理器控制一致性。

對于 TCC 的解釋:

  • Try 階段:嘗試執(zhí)行,完成所有業(yè)務檢查(一致性),預留必需業(yè)務資源(準隔離性)。

  • Confirm 階段:確認真正執(zhí)行業(yè)務,不作任何業(yè)務檢查,只使用 Try 階段預留的業(yè)務資源,Confirm 操作滿足冪等性。要求具備冪等設計,Confirm 失敗后需要進行重試。

  • Cancel 階段:取消執(zhí)行,釋放 Try 階段預留的業(yè)務資源,Cancel 操作滿足冪等性。Cancel 階段的異常和 Confirm 階段異常處理方案基本上一致。

舉個簡單的例子:如果你用 100 元買了一瓶水, Try 階段:你需要向你的錢包檢查是否夠 100 元并鎖住這 100 元,水也是一樣的。

如果有一個失敗,則進行 Cancel(釋放這 100 元和這一瓶水),如果 Cancel 失敗不論什么失敗都進行重試 Cancel,所以需要保持冪等。

如果都成功,則進行 Confirm,確認這 100 元被扣,和這一瓶水被賣,如果 Confirm 失敗無論什么失敗則重試(會依靠活動日志進行重試)。

對于 TCC 來說適合一些:

  • 強隔離性,嚴格一致性要求的活動業(yè)務。

  • 執(zhí)行時間較短的業(yè)務。

實現(xiàn)參考:https://github.com/liuyangming/ByteTCC/。

本地消息表

本地消息表這個方案最初是 eBay 提出的,eBay 的完整方案 https://queue.acm.org/detail.cfm?id=1394128。

此方案的核心是將需要分布式處理的任務通過消息日志的方式來異步執(zhí)行。消息日志可以存儲到本地文本、數(shù)據(jù)庫或消息隊列,再通過業(yè)務規(guī)則自動或人工發(fā)起重試。

人工重試更多的是應用于支付場景,通過對賬系統(tǒng)對事后問題的處理。

對于本地消息隊列來說核心是把大事務轉變?yōu)樾∈聞?。還是舉上面用 100 元去買一瓶水的例子。

1. 當你扣錢的時候,你需要在你扣錢的服務器上新增加一個本地消息表,你需要把你扣錢和減去水的庫存寫入到本地消息表,放入同一個事務(依靠數(shù)據(jù)庫本地事務保證一致性)。

2. 這個時候有個定時任務去輪詢這個本地事務表,把沒有發(fā)送的消息,扔給商品庫存服務器,叫它減去水的庫存,到達商品服務器之后,這時得先寫入這個服務器的事務表,然后進行扣減,扣減成功后,更新事務表中的狀態(tài)。

3. 商品服務器通過定時任務掃描消息表或者直接通知扣錢服務器,扣錢服務器在本地消息表進行狀態(tài)更新。

4. 針對一些異常情況,定時掃描未成功處理的消息,進行重新發(fā)送,在商品服務器接到消息之后,首先判斷是否是重復的。

如果已經(jīng)接收,再判斷是否執(zhí)行,如果執(zhí)行在馬上又進行通知事務;如果未執(zhí)行,需要重新執(zhí)行由業(yè)務保證冪等,也就是不會多扣一瓶水。

本地消息隊列是 BASE 理論,是最終一致模型,適用于對一致性要求不高的情況。實現(xiàn)這個模型時需要注意重試的冪等。

MQ 事務

在 RocketMQ 中實現(xiàn)了分布式事務,實際上是對本地消息表的一個封裝,將本地消息表移動到了 MQ 內(nèi)部。

下面簡單介紹一下MQ事務,如果想對其詳細了解可以參考:https://www.jianshu.com/p/453c6e7ff81c。

基本流程如下:

  • ***階段 Prepared 消息,會拿到消息的地址。

  • 第二階段執(zhí)行本地事務。

  • 第三階段通過***階段拿到的地址去訪問消息,并修改狀態(tài)。消息接受者就能使用這個消息。

如果確認消息失敗,在 RocketMQ Broker 中提供了定時掃描沒有更新狀態(tài)的消息。

如果有消息沒有得到確認,會向消息發(fā)送者發(fā)送消息,來判斷是否提交,在 RocketMQ 中是以 Listener 的形式給發(fā)送者,用來處理。

如果消費超時,則需要一直重試,消息接收端需要保證冪等。如果消息消費失敗,這時就需要人工進行處理,因為這個概率較低,如果為了這種小概率時間而設計這個復雜的流程反而得不償失。

Saga 事務

Saga 是 30 年前一篇數(shù)據(jù)庫倫理提到的一個概念。其核心思想是將長事務拆分為多個本地短事務,由 Saga 事務協(xié)調(diào)器協(xié)調(diào),如果正常結束那就正常完成,如果某個步驟失敗,則根據(jù)相反順序一次調(diào)用補償操作。

Saga 的組成:每個 Saga 由一系列 sub-transaction Ti 組成,每個 Ti 都有對應的補償動作 Ci,補償動作用于撤銷 Ti 造成的結果。這里的每個 T,都是一個本地事務。

可以看到,和 TCC 相比,Saga 沒有“預留 try”動作,它的 Ti 就是直接提交到庫。

Saga 的執(zhí)行順序有兩種:

  • T1,T2,T3,...,Tn。

  • T1,T2,...,Tj,Cj,...,C2,C1,其中 0 < j < n 。

Saga 定義了兩種恢復策略:

  • 向后恢復,即上面提到的第二種執(zhí)行順序,其中 j 是發(fā)生錯誤的 sub-transaction,這種做法的效果是撤銷掉之前所有成功的 sub-transation,使得整個 Saga 的執(zhí)行結果撤銷。

  • 向前恢復,適用于必須要成功的場景,執(zhí)行順序是類似于這樣的:T1,T2,...,Tj(失敗),Tj(重試),...,Tn,其中 j 是發(fā)生錯誤的 sub-transaction。該情況下不需要 Ci。

這里要注意的是,在 Saga 模式中不能保證隔離性,因為沒有鎖住資源,其他事務依然可以覆蓋或者影響當前事務。

還是拿 100 元買一瓶水的例子來說,這里定義:

  • T1 = 扣 100 元,T2 = 給用戶加一瓶水,T3 = 減庫存一瓶水。

  • C1 = 加100元,C2 = 給用戶減一瓶水,C3 = 給庫存加一瓶水。

我們一次進行 T1,T2,T3 如果發(fā)生問題,就執(zhí)行發(fā)生問題的 C 操作的反向。

上面說到的隔離性的問題會出現(xiàn)在,如果執(zhí)行到 T3 這個時候需要執(zhí)行回滾,但是這個用戶已經(jīng)把水喝了(另外一個事務),回滾的時候就會發(fā)現(xiàn),無法給用戶減一瓶水了。

這就是事務之間沒有隔離性的問題。可以看見 Saga 模式?jīng)]有隔離性的影響還是較大,可以參照華為的解決方案:從業(yè)務層面入手加入一 Session 以及鎖的機制來保證能夠串行化操作資源。

也可以在業(yè)務層面通過預先凍結資金的方式隔離這部分資源, ***在業(yè)務操作的過程中可以通過及時讀取當前狀態(tài)的方式獲取到***的更新。(具體實例:可以參考華為的 Service Comb)

***

還是那句話,能不用分布式事務就不用,如果非得使用的話,結合自己的業(yè)務分析,看看自己的業(yè)務比較適合哪一種,是在乎強一致,還是最終一致即可。

***在總結一些問題,大家可以下來自己從文章找尋答案:

  • ACID 和 CAP 的 CA 是一樣的嗎?

  • 分布式事務常用的解決方案的優(yōu)缺點是什么?適用于什么場景?

  • 分布式事務出現(xiàn)的原因?用來解決什么痛點?

到此,相信大家對“分布式事務是什么意思”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

當前文章:分布式事務是什么意思
本文URL:http://bm7419.com/article40/igseeo.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供關鍵詞優(yōu)化、定制開發(fā)網(wǎng)站營銷、自適應網(wǎng)站、網(wǎng)站策劃、虛擬主機

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化