成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

關(guān)于微服務(wù)系統(tǒng)中數(shù)據(jù)一致性的總結(jié)

開發(fā) 架構(gòu)
本文主要總結(jié)了本地事務(wù)、全局事務(wù)、最終一致性等方式實(shí)現(xiàn)數(shù)據(jù)自洽。重點(diǎn)介紹了實(shí)現(xiàn)最終一致性的集中模式:可靠事件模式、TCC 模式、SAGA 模式等。數(shù)據(jù)的一致性一直是個難題,隨著微服務(wù)化之后,數(shù)據(jù)一致性更加困難,有困難不怕,只要不放棄,總會解決的。

[[432634]]

你好,我是看山。

從單體架構(gòu)到分布式架構(gòu),從巨石架構(gòu)到微服務(wù)架構(gòu)。系統(tǒng)之間的交互越來越復(fù)雜,系統(tǒng)間的數(shù)據(jù)交互量級也是指數(shù)級增長。作為一個系統(tǒng),我們要保證邏輯的自洽和數(shù)據(jù)的自洽。

數(shù)據(jù)自洽有兩方面要求:

  • 拋開代碼,數(shù)據(jù)能夠自己驗(yàn)證自己的準(zhǔn)確性,也就是數(shù)據(jù)彼此之間不矛盾
  • 所有數(shù)據(jù)準(zhǔn)確且符合期望

為了實(shí)現(xiàn)這兩點(diǎn),需要實(shí)現(xiàn)數(shù)據(jù)的一致性,為了實(shí)現(xiàn)一致性,就需要用到事務(wù)。

需要注意一下,本文所設(shè)計(jì)的數(shù)據(jù)一致性,不是多數(shù)據(jù)副本之間保持?jǐn)?shù)據(jù)一致性,而是系統(tǒng)之間的業(yè)務(wù)數(shù)據(jù)保持一致性。

本地事務(wù)

在早期的系統(tǒng)中,我們可以通過關(guān)系型數(shù)據(jù)庫的事務(wù)保證數(shù)據(jù)的一致性。這種事務(wù)有四個基本要素:ACID。

  • A(Atomicity,原子性):整個事務(wù)中的所有操作,要么全部完成,要么全部失敗,不可能停滯在中間某個環(huán)節(jié)。事務(wù)在執(zhí)行過程中發(fā)生錯誤,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣。
  • C(Consistency,一致性):一個事務(wù)可以封裝狀態(tài)改變(除非它是一個只讀的)。事務(wù)必須始終保持系統(tǒng)處于一致的狀態(tài),不管在任何給定的時間并發(fā)事務(wù)有多少。
  • I(Isolation,隔離性):隔離狀態(tài)執(zhí)行事務(wù),使它們好像是系統(tǒng)在給定時間內(nèi)執(zhí)行的唯一操作。如果有兩個事務(wù),運(yùn)行在相同的時間內(nèi),執(zhí)行相同的功能,事務(wù)的隔離性將確保每一事務(wù)在系統(tǒng)中認(rèn)為只有該事務(wù)在使用系統(tǒng)。這種屬性有時稱為串行化,為了防止事務(wù)操作間的混淆,必須串行化或序列化請求,使得在同一時間僅有一個請求用于同一數(shù)據(jù)。
  • D(Durability,持久性):在事務(wù)完成以后,該事務(wù)對數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中,并不會被回滾。

這四個要素是關(guān)系型數(shù)據(jù)庫的根本。無論系統(tǒng)多么復(fù)雜,只要使用同一個關(guān)系型數(shù)據(jù)庫,我們就可以借助事務(wù)保證數(shù)據(jù)一致性?;趯﹃P(guān)系型數(shù)據(jù)庫的信任,我們可以認(rèn)為本地事務(wù)是可靠的,開發(fā)過程中不需要額外的工作。從架構(gòu)的角度,關(guān)系型數(shù)據(jù)庫也是一個單獨(dú)的系統(tǒng),那關(guān)系型數(shù)據(jù)庫與應(yīng)用之間也是形成了分布式。所以我們先研究一下這種簡單的分布式系統(tǒng)如何實(shí)現(xiàn) ACID。

首先,A(原子性)和 D(持久性)是彼此之間密不可分的兩個屬性:原子性保證了事務(wù)的所有操作,要么全部完成,要么全部失敗,不可能停滯在中間某個環(huán)節(jié);持久性保證了一旦事務(wù)完成,該事務(wù)對數(shù)據(jù)庫所作的更改便持久的保存在數(shù)據(jù)庫之中,不會因?yàn)槿魏卧蚨鴮?dǎo)致其修改的內(nèi)容被撤銷或丟失。

眾所周知,數(shù)據(jù)必須寫入到磁盤后才能保證持久化,僅僅保存在內(nèi)存中,一旦出現(xiàn)系統(tǒng)崩潰、主機(jī)斷電等情況,數(shù)據(jù)就會丟失。所以,關(guān)鍵是“寫入磁盤”要實(shí)現(xiàn)原子性和持久性,然而這個動作存在中間態(tài):正在寫入。所以,現(xiàn)代的關(guān)系型數(shù)據(jù)庫通常采用追加日志記錄的方式。將修改數(shù)據(jù)所需的全部信息(包括修改什么數(shù)據(jù)、數(shù)據(jù)物理上位于哪個內(nèi)存頁和磁盤塊中、從什么值改成什么值,等等),以順序追加的形式記錄到磁盤中。只有在日志記錄全部落盤,數(shù)據(jù)庫在日志中看到代表事務(wù)成功提交的“提交記錄”后,才會根據(jù)日志上的信息對真正的數(shù)據(jù)進(jìn)行修改。修改完成后,再在日志中加入一條“結(jié)束記錄”表示事務(wù)已完成持久化,這種事務(wù)實(shí)現(xiàn)方法被稱為“提交日志”。

本地事務(wù)

我們能夠通過日志保證一個事務(wù)的原子性和持久性,那如果出現(xiàn)多個事務(wù)訪問同一個資源呢?作為程序猿都知道,多個線程/進(jìn)程訪問同一個資源,這個資源就稱為臨界資源,想要解決臨界資源占用沖突的方式很簡單,就是加鎖。關(guān)系型數(shù)據(jù)庫為我們準(zhǔn)備了三種鎖:

  • 寫鎖(Write Lock):同一個時刻,只有有一個事務(wù)對數(shù)據(jù)加寫鎖,所以寫鎖也被稱為排它鎖(exclusive Lock)。數(shù)據(jù)被加了寫鎖后,其他事務(wù)不能寫入數(shù)據(jù),也不能對其添加讀鎖(注意,是不能加讀鎖,但是可以讀取數(shù)據(jù))。
  • 讀鎖(Read Lock):同一時刻,多個事務(wù)可以對數(shù)據(jù)添加讀鎖,所以讀鎖也被稱為共享鎖(Shared Lock)。數(shù)據(jù)庫被添加讀鎖后,數(shù)據(jù)不能被添加寫鎖。
  • 范圍鎖(Range Lock):對一個范圍的數(shù)據(jù)添加寫鎖,這個范圍的數(shù)據(jù)不能被寫入。也可以算作寫鎖的批量行為。

根據(jù)這三種鎖的不同組合,我們可以實(shí)現(xiàn)四種不同的事務(wù)隔離級別:

  • 可串行化(Serializable):寫入的時候加寫鎖,讀取的時候加讀鎖,范圍讀寫的時候加范圍鎖。
  • 可重復(fù)度(Repeatable Read):寫入的時候加寫鎖,讀取的時候加讀鎖,范圍讀寫的時候不加鎖,這樣會出現(xiàn)讀取相同范圍數(shù)據(jù)的時候,返回結(jié)果不同,即幻讀(Phantom Read)。
  • 讀已提交(Read Committed):寫入的時候加寫鎖,讀取的時候加讀鎖,讀取完成后立馬釋放讀鎖。這樣會出現(xiàn)同一個事務(wù)多次讀取相同數(shù)據(jù),返回結(jié)果不同,即不可重復(fù)讀(Non-Repeatable Read)。
  • 讀未提交(Read Uncommitted):寫入的時候加寫鎖,讀取的時候不加鎖。這樣就會讀取到另一個還未提交的事務(wù)寫入的數(shù)據(jù),即臟讀(Dirty Read)。

全局事務(wù)

隨著系統(tǒng)規(guī)模不斷擴(kuò)大,業(yè)務(wù)量不斷增加。單體應(yīng)用不再滿足需求,我們會拆分系統(tǒng),然后拆分?jǐn)?shù)據(jù)庫。此時,同一個請求中,就會出現(xiàn)同時訪問多個數(shù)據(jù)庫的情況。為了解決這種情況的數(shù)據(jù)一致性問題,X/Open 組織在 1991 年(那個時候我還小)提出了一套 X/Open XA 的處理事務(wù)的架構(gòu)。XA 的核心內(nèi)容是定義了全局的事務(wù)管理器(Transaction Manager,用于協(xié)調(diào)全局事務(wù))和局部的資源管理器(Resource Manager,用于驅(qū)動本地事務(wù))之間的通信接口,在一個事務(wù)管理器和多個資源管理器(Resource Manager)之間形成通信橋梁,通過協(xié)調(diào)多個數(shù)據(jù)源的一致動作,實(shí)現(xiàn)全局事務(wù)的統(tǒng)一提交或者統(tǒng)一回滾。與 XA 架構(gòu)配套的是兩階段提交協(xié)議(2PC,Two Phase Commitment Protocol)。在這個協(xié)議中,最關(guān)鍵的點(diǎn)就是,多個數(shù)據(jù)庫的活動,均由一個事務(wù)協(xié)調(diào)器的組件來控制。具體的分為 5 個步驟:

  1. 應(yīng)用程序調(diào)用事務(wù)管理器中的提交方法
  2. 事務(wù)管理器將聯(lián)絡(luò)事務(wù)中涉及的每個數(shù)據(jù)庫,并通知它們準(zhǔn)備提交事務(wù)(這是第一階段的開始)
  3. 接收到準(zhǔn)備提交事務(wù)通知后,數(shù)據(jù)庫必須確保能在被要求提交事務(wù)時提交事務(wù),或在被要求回滾事務(wù)時回滾事務(wù)。如果數(shù)據(jù)庫無法準(zhǔn)備事務(wù),它會以一個否定響應(yīng)來回應(yīng)事務(wù)管理器。
  4. 事務(wù)管理器收集來自各數(shù)據(jù)庫的所有響應(yīng)。
  5. 在第二階段,事務(wù)管理器將事務(wù)的結(jié)果通知給每個數(shù)據(jù)庫。如果任一數(shù)據(jù)庫做出否定響應(yīng),則事務(wù)管理器會將一個回滾命令發(fā)送給事務(wù)中涉及的所有數(shù)據(jù)庫。如果數(shù)據(jù)庫都做出肯定響應(yīng),則事務(wù)管理器會指示所有的資源管理器提交事務(wù)。一旦通知數(shù)據(jù)庫提交,此后的事務(wù)就不能失敗了。通過以肯定的方式響應(yīng)第一階段,每個資源管理器均已確保,如果以后通知它提交事務(wù),則事務(wù)不會失敗。

2PC

兩階段提交協(xié)議實(shí)現(xiàn)簡單,但存在幾個明顯缺陷:

  • 單點(diǎn)問題:事務(wù)管理器在兩段提交中具有舉足輕重的作用,事務(wù)管理器等待資源管理器回復(fù)時可以有超時機(jī)制,允許資源管理器宕機(jī),但資源管理器等待事務(wù)管理器指令時無法做超時處理。一旦宕機(jī)的不是其中某個資源管理器,而是事務(wù)管理器的話,所有資源管理器都會受到影響。如果事務(wù)管理器一直沒有恢復(fù),沒有正常發(fā)送 Commit 或者 Rollback 的指令,那所有資源管理器都必須一直等待。
  • 性能問題:兩段提交過程中,所有資源管理器相當(dāng)于被綁定成為一個統(tǒng)一調(diào)度的整體,期間要經(jīng)過兩次遠(yuǎn)程服務(wù)調(diào)用,三次數(shù)據(jù)持久化(準(zhǔn)備階段寫重做日志,事務(wù)管理器做狀態(tài)持久化,提交階段在日志寫入 Commit Record),整個過程將持續(xù)到資源管理器集群中最慢的那一個處理操作結(jié)束為止,這決定了兩段式提交的性能通常都較差。
  • 一致性風(fēng)險:盡管提交階段時間很短,但這仍是一段明確存在的危險期。如果事務(wù)管理器在發(fā)出準(zhǔn)備指令后,根據(jù)收到各個資源管理器發(fā)回的信息確定事務(wù)狀態(tài)是可以提交的,事務(wù)管理器會先持久化事務(wù)狀態(tài),并提交自己的事務(wù),如果這時候網(wǎng)絡(luò)斷開,無法再通過網(wǎng)絡(luò)向所有資源管理器發(fā)出 Commit 指令的話,就會導(dǎo)致部分?jǐn)?shù)據(jù)(事務(wù)管理器的)已提交,但部分?jǐn)?shù)據(jù)(資源管理器的)既未提交,也沒有辦法回滾,產(chǎn)生了數(shù)據(jù)不一致的問題。

能夠發(fā)現(xiàn)問題,就能夠想到辦法解決。我們高中老師說了,只要意識不滑坡,辦法總比困難多。所以又發(fā)展出了三階段提交協(xié)議(3PC,Three Phase Commitment Protocol),能夠緩解單點(diǎn)問題和準(zhǔn)備階段的性能問題。這個協(xié)議把 2PC 中的準(zhǔn)備階段拆分為 CanCommit 和 PreCommit,把提交階段改名為 DoCommit。CanCommit 是詢問階段,讓每個資源管理器根據(jù)自身情況判斷該事務(wù)是否有可能完成。

3PC 本質(zhì)是通過一次問詢,如果大家都說自己可以,那成事的可能性很大,減少了準(zhǔn)備階段直接鎖定資源的重操作。由于事務(wù)失敗回滾概率變小的原因,在三段式提交中,如果在 PreCommit 階段之后發(fā)生了事務(wù)管理器宕機(jī),即資源管理器沒有能等到 DoCommit 的消息的話,默認(rèn)的操作策略將是提交事務(wù)而不是回滾事務(wù)或者持續(xù)等待,這就相當(dāng)于避免了事務(wù)管理器單點(diǎn)問題的風(fēng)險。

3PC

分布式事務(wù)

說到分布式事務(wù),不得不提 CAP 理論:任何分布式系統(tǒng)只可同時滿足一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition tolerance)中的兩點(diǎn),沒法三者兼顧。

CAP 理論

  • 一致性(Consistency):數(shù)據(jù)在任何時刻、任何分布式節(jié)點(diǎn)中所看到的都是符合預(yù)期的。
  • 可用性(Availability):系統(tǒng)不間斷地提供服務(wù)的能力,可用性是由可靠性(Reliability)和可維護(hù)性(Serviceability)計(jì)算得出的比例值??煽啃酝ㄟ^平均無故障時間(Mean Time Between Failure,MTBF)來度量;可維護(hù)性通過平均可修復(fù)時間(Mean Time To Repair,MTTR)來度量??捎眯院饬肯到y(tǒng)可以正常使用的時間與總時間之比,公式為:A=MTBF/(MTBF+MTTR)。
  • 分區(qū)容錯性(Partition Tolerance):分布式環(huán)境中部分節(jié)點(diǎn)因網(wǎng)絡(luò)原因而彼此失聯(lián)后,系統(tǒng)仍能正確地提供服務(wù)的能力。

CAP 理論定義是經(jīng)過幾次修改的,修改后的定義本質(zhì)沒有區(qū)別,只是在邏輯上更加嚴(yán)謹(jǐn)。本文為了好理解,使用了最容易讓大眾接收并理解的定義。

既然 CAP 不能兼顧,那我們來看看缺少其中一環(huán)會出現(xiàn)什么情況:

  • 選擇 CA 放棄 P:即我們認(rèn)為網(wǎng)絡(luò)可靠不會出現(xiàn)分區(qū)情況,這種可靠是各個節(jié)點(diǎn)之間不會出現(xiàn)網(wǎng)絡(luò)延遲、中斷等情況,顯然是不成立的。
  • 選擇 CP 放棄 A:這樣做就是拋棄了可用性,為了保證數(shù)據(jù)一致性,一旦出現(xiàn)網(wǎng)絡(luò)異常,節(jié)點(diǎn)之間的信息同步時間可以無限制地延長。使用 CP 組合的一般用于對數(shù)據(jù)質(zhì)量要求很高的場合,也就是為了保證數(shù)據(jù)完全一致,暫時不提供服務(wù),直到網(wǎng)絡(luò)完全恢復(fù),這可能持續(xù)一個不確定的時間,尤其是在系統(tǒng)已經(jīng)表現(xiàn)出高延遲時或者網(wǎng)絡(luò)故障導(dǎo)致失去連接時。
  • 選擇 AP 放棄 C:意味著一旦發(fā)生網(wǎng)絡(luò)分區(qū),優(yōu)先提供服務(wù)可用,放棄數(shù)據(jù)一致性。這是目前分布式系統(tǒng)的主流選擇,因?yàn)榫W(wǎng)絡(luò)本身就是鏈接不同區(qū)域的服務(wù)器的,網(wǎng)絡(luò)又是不可靠的,所以 P 不能被舍棄。同時,我們實(shí)現(xiàn)分布式系統(tǒng)就是為了提高可用性,這是我們的目的,不能舍棄。

這里需要再說明一下,我們選擇 AP 放棄 C 不是放棄數(shù)據(jù)一致,而是暫時放棄強(qiáng)一致性(Strong Consistency),而是選擇弱一致性,即最終一致性(Eventual Consistency):系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一段時間后,最終能夠達(dá)到一致的狀態(tài)。這里所說的一段時間,也要是用戶可接受范圍內(nèi)的一段時間。

最終一致性也有一個理論支撐:BASE 理論(不得不說,理論界的縮寫真牛啊,ACID 是酸,CAP 是帽子,BASE 是堿),內(nèi)容主要包括:

  • 基本可用(Basically Available):當(dāng)系統(tǒng)在出現(xiàn)不可預(yù)知故障的時候,允許損失部分可用性。比如,允許響應(yīng)時間增長,允許部分非關(guān)鍵接口降級或熔斷等。
  • 軟狀態(tài)(Soft State):軟狀態(tài)也稱為弱狀態(tài),和硬狀態(tài)相對。是指允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),并認(rèn)為該中間狀態(tài)的存在不會影響系統(tǒng)的整體可用性,即允許系統(tǒng)在不同節(jié)點(diǎn)的數(shù)據(jù)副本之間進(jìn)行數(shù)據(jù)同步的過程存在延時。
  • 最終一致性(Eventually Consistent):最終一致性強(qiáng)調(diào)的是系統(tǒng)中所有的數(shù)據(jù)副本,在經(jīng)過一段時間的同步后,最終能夠達(dá)到一個一致的狀態(tài)。因此,最終一致性的本質(zhì)是需要系統(tǒng)保證最終數(shù)據(jù)能夠達(dá)到一致,而不需要實(shí)時保證系統(tǒng)數(shù)據(jù)的強(qiáng)一致性。

在工程實(shí)踐中,最終一致性分為 5 種,這 5 種方式會結(jié)合使用,共同實(shí)現(xiàn)最終一致性:

  • 因果一致性(Causal consistency):如果節(jié)點(diǎn) A 在更新完某個數(shù)據(jù)后通知了節(jié)點(diǎn) B,那么節(jié)點(diǎn) B 之后對該數(shù)據(jù)的訪問和修改都是基于 A 更新后的值。于此同時,和節(jié)點(diǎn) A 無因果關(guān)系的節(jié)點(diǎn) C 的數(shù)據(jù)訪問則沒有這樣的限制。
  • 讀己之所寫(Read your writes):節(jié)點(diǎn) A 更新一個數(shù)據(jù)后,它自身總是能訪問到自身更新過的最新值,而不會看到舊值。
  • 會話一致性(Session consistency):會話一致性將對系統(tǒng)數(shù)據(jù)的訪問過程框定在了一個會話當(dāng)中,系統(tǒng)能保證在同一個有效的會話中實(shí)現(xiàn)“讀己之所寫”的一致性,也就是說,執(zhí)行更新操作之后,客戶端能夠在同一個會話中始終讀取到該數(shù)據(jù)項(xiàng)的最新值。
  • 單調(diào)讀一致性(Monotonic read consistency):如果一個節(jié)點(diǎn)從系統(tǒng)中讀取出一個數(shù)據(jù)項(xiàng)的某個值后,那么系統(tǒng)對于該節(jié)點(diǎn)后續(xù)的任何數(shù)據(jù)訪問都不應(yīng)該返回更舊的值。
  • 單調(diào)寫一致性(Monotonic write consistency):一個系統(tǒng)要能夠保證來自同一個節(jié)點(diǎn)的寫操作被順序的執(zhí)行。

一致性關(guān)系模型

有了理論之后,我們來說一下實(shí)現(xiàn)最終一致性的幾種模式。

可靠事件模式

可靠事件模式屬于事件驅(qū)動架構(gòu):當(dāng)某個事件發(fā)生時,例如更新一個業(yè)務(wù)實(shí)體,服務(wù)會向消息代理發(fā)布一個事件。消息代理會向訂閱事件的服務(wù)推送事件,當(dāng)訂閱這些事件的服務(wù)接收此事件時,就可以完成自己的業(yè)務(wù),也可能會引發(fā)更多的事件發(fā)布。

我們通過一個例子來解釋一下這種模式,用戶下單成功后,訂單系統(tǒng)需要通知庫存系統(tǒng)減庫存。

可靠事件模式

  1. 訂單系統(tǒng)根據(jù)用戶操作完成下單操作。此時會使用同一個本地事務(wù)保存訂單信息和寫入事件。
  2. 另外一個消息服務(wù)會輪詢事件表,將狀態(tài)是“進(jìn)行中”的事件以消息形式發(fā)送到消息服務(wù)中。如果發(fā)送失敗,因?yàn)槭禽喸內(nèi)蝿?wù),會在下一次輪詢的時候再次發(fā)送。(此處有一些優(yōu)化點(diǎn),本例為了簡化模型,不展開)
  3. 消息服務(wù)向訂閱下單消息的庫存服務(wù)發(fā)送下單成功消息,庫存服務(wù)開始處理。此時會有這么集中情況:
  • 庫存服務(wù)扣減庫存成功,消息服務(wù)接收到處理成功響應(yīng)。消息服務(wù)將響應(yīng)結(jié)果返回給訂單服務(wù),訂單服務(wù)中事件接收器將事件修改為“已完成”。
  • 庫存服務(wù)扣減庫存失敗,消息服務(wù)接收到處理失敗響應(yīng)。此時消息服務(wù)會再次向庫存服務(wù)發(fā)送消息,直到得到成功響應(yīng)。如果失敗次數(shù)達(dá)到閾值,可以告警通知人工介入。
  • 消息服務(wù)給訂單服務(wù)返回結(jié)果時,發(fā)生失敗,訂單服務(wù)沒有接收到成功響應(yīng)。這個時候,事件輪詢邏輯會再次將事件發(fā)送給消息服務(wù)。這樣,庫存服務(wù)會重復(fù)收到扣減庫存的消息,所以要求庫存服務(wù)做好冪等。庫存服務(wù)發(fā)現(xiàn)消息已經(jīng)處理過,直接返回成功。

這種靠著持續(xù)重試來保證可靠性的解決方案,叫做“最大努力交付”(Best-Effort Delivery),也是“可靠”兩個字的來源。

可靠事件模式還有一種更普通的形式,被稱為“最大努力一次提交”(Best-Effort 1PC),指的就是將最有可能出錯或最核心的業(yè)務(wù)以本地事務(wù)的方式完成后,采用不斷重試的方式(不限于消息服務(wù))來促使同一個分布式事務(wù)中的其他關(guān)聯(lián)業(yè)務(wù)全部完成。找到最可能出錯的方式是提前做好出錯概率的先驗(yàn)評估,才能夠知道哪塊最容易出錯。找到最核心的業(yè)務(wù)的方式是找到那種只要成功,其他業(yè)務(wù)必須成功的那塊業(yè)務(wù)。

這里我們再補(bǔ)充兩個概念:

  • 業(yè)務(wù)異常:業(yè)務(wù)邏輯產(chǎn)生錯誤的情況,比如賬戶余額不足、商品庫存不足等。
  • 技術(shù)異常:非業(yè)務(wù)邏輯產(chǎn)生的異常,如網(wǎng)絡(luò)連接異常、網(wǎng)絡(luò)超時等。

TCC 模式

TCC(Try-Confirm-Cancel)是一種業(yè)務(wù)侵入式較強(qiáng)的事務(wù)方案,要求業(yè)務(wù)處理過程必須拆分為“預(yù)留業(yè)務(wù)資源”和“確認(rèn)/釋放消費(fèi)資源”兩個子過程,由統(tǒng)一的服務(wù)協(xié)調(diào)調(diào)度不同業(yè)務(wù)系統(tǒng)的子過程。分為以下三個階段:

  • Try:嘗試執(zhí)行階段,完成所有業(yè)務(wù)可執(zhí)行性的檢查(保障一致性),并且預(yù)留好全部需要用到的業(yè)務(wù)資源(保障隔離性)。
  • Confirm:確認(rèn)執(zhí)行階段,不進(jìn)行任何業(yè)務(wù)檢查,直接使用 Try 階段準(zhǔn)備的資源來完成業(yè)務(wù)處理。Confirm 階段可能會重復(fù)執(zhí)行,需要滿足冪等性。
  • Cancel:取消執(zhí)行階段,釋放 Try 階段預(yù)留的業(yè)務(wù)資源。Cancel 階段可能會重復(fù)執(zhí)行,需要滿足冪等性。

TCC 模式

1.訂單系統(tǒng)創(chuàng)建事務(wù),生成事務(wù) ID(用于作為識別請求冪等的標(biāo)識),通過活動管理器記錄活動日志。

2.進(jìn)入 Try 階段

  • 調(diào)用賬戶系統(tǒng),檢查賬戶余額是否充足,如果充足,凍結(jié)需要的金額,此時賬戶余額是臨界資源,需要通過排它鎖或樂觀鎖保證凍結(jié)操作的安全性。
  • 調(diào)用庫存系統(tǒng),檢查商品庫存是否充足,如果充足,鎖定需要的庫存,鎖庫操作也需要加鎖保證安全

3.如果所有業(yè)務(wù)返回成功,記錄活動日志為 Confirm,進(jìn)入 Confirm 階段:

  • 調(diào)用賬戶系統(tǒng),扣減凍結(jié)的金額
  • 調(diào)用庫存系統(tǒng),扣減鎖定的庫存

4.第 3 步操作中如果全部完成,事務(wù)宣告結(jié)束。如果第 3 步中任何一方出現(xiàn)異常,都會根據(jù)活動日志中的記錄,重復(fù)執(zhí)行 Confirm 操作,即進(jìn)行最大努力交付。所以各業(yè)務(wù)系統(tǒng)的 Confirm 操作需要實(shí)現(xiàn)冪等性。

5.如果第 2 步有任何一方失敗(包括業(yè)務(wù)異常和技術(shù)異常),將活動日志記錄為 Cancel,進(jìn)入 Cancel 階段:

  • 調(diào)用賬戶系統(tǒng),釋放凍結(jié)的金額
  • 調(diào)用庫存系統(tǒng),釋放鎖定的庫存

6.第 5 步操作中如果全部完成,事務(wù)宣告失敗。如果第 5 步中任何一方出現(xiàn)異常(包括業(yè)務(wù)異常和技術(shù)異常),都會根據(jù)活動日志中的記錄,重復(fù)執(zhí)行 Cacel 操作,即最大努力交付。所以各業(yè)務(wù)系統(tǒng)的 Cancel 操作也需要實(shí)現(xiàn)冪等性。

是不是感覺 TCC 與 2PC 的很像,兩者的區(qū)別在于,TCC 位于業(yè)務(wù)代碼層面,屬于白盒,2PC 位于基礎(chǔ)設(shè)施層面,屬于黑盒。所以 TCC 有更高的靈活性,可以根據(jù)需要,調(diào)整資源鎖定的粒度。

TCC 在業(yè)務(wù)執(zhí)行過程中可以預(yù)留資源,解決了可靠事件模式的資源隔離問題。但是,TCC 還有兩個明顯缺點(diǎn):

  1. TCC 將基礎(chǔ)設(shè)施層的邏輯上移到業(yè)務(wù)代碼,對業(yè)務(wù)有很高的侵入性,需要更高的開發(fā)成本,開發(fā)成本提升,相對應(yīng)的維護(hù)成本、開發(fā)人員的素質(zhì)等,都會有更高的要求。
  2. TCC 要求資源可以鎖定、占用或釋放,但是有的資源屬于外部系統(tǒng),沒有辦法實(shí)現(xiàn)鎖定。

鑒于上面的兩個缺點(diǎn),我們看看 SAGA 是否可以彌補(bǔ)。

SAGA 模式

SAGA 在英文中是“長篇故事、長篇記敘、一長串事件”的意思。SAGA 模式的提出遠(yuǎn)早于分布式事務(wù)概念的提出(再次對前輩大佬佩服的五體投地),它源于 1987 年普林斯頓大學(xué)的 Hector Garcia-Molina 和 Kenneth Salem 在 ACM 發(fā)表的一篇論文《SAGAS》。文中提出了一種提升“長時間事務(wù)”(Long Lived Transaction)運(yùn)作效率的方法,大致思路是把一個大事務(wù)分解為可以交錯運(yùn)行的一系列子事務(wù)集合,后來發(fā)展成將一個分布式環(huán)境中的大事務(wù)分解為一系列本地事務(wù)的設(shè)計(jì)模式。在有的文章中,將這種模式稱為業(yè)務(wù)補(bǔ)償模式,SAGA 是對事務(wù)形式的描述,業(yè)務(wù)補(bǔ)償是對事務(wù)行為的描述,其本質(zhì)是一樣的。

SAGA 模式有兩種實(shí)現(xiàn):

  • 正向恢復(fù)(Forward Recovery):順序執(zhí)行各個子事務(wù),如果遇到某個子事務(wù)執(zhí)行失敗,將一直重試該操作,知道成功,然后繼續(xù)執(zhí)行下一個子事務(wù)。比如用戶下單支付成功了,就一定要扣減庫存。
  • 反向恢復(fù)(Backward Recovery):順序執(zhí)行各個子事務(wù),如果遇到某個子事務(wù)執(zhí)行失敗,將執(zhí)行該子事務(wù)的補(bǔ)償操作(避免因?yàn)榧夹g(shù)異常造成的失敗,補(bǔ)償操作需要冪等),然后倒序執(zhí)行已經(jīng)成功的子事務(wù)的補(bǔ)償操作。這種一般是可取消的批量操作,比如出行訂票,需要購買飛機(jī)票、訂酒店、買門票,如果買門票失敗了,飛機(jī)票和酒店就可以取消了。

SAGA 模式

根據(jù)這兩種實(shí)現(xiàn),SAGA 可以分為兩部分:

  • 子事務(wù)(Normal Transactions):大事務(wù)拆分若干個小事務(wù),將整個事務(wù) T 分解為 n 個子事務(wù),命名為 T1、T2、…、Tn。每個子事務(wù)都應(yīng)該是或者能被視為是原子行為。如果分布式事務(wù)能夠正常提交,其對數(shù)據(jù)的影響(最終一致性)應(yīng)與連續(xù)按順序成功提交 Ti 等價。
  • 補(bǔ)償事務(wù)(Compensating Transactions):每個子事務(wù)對應(yīng)的補(bǔ)償動作,命名為 C1、C2、…、Cn。

子事務(wù)與補(bǔ)償動作需要滿足一些條件:

  • Ti與 Ci必須對應(yīng)
  • 補(bǔ)償動作 Ci一定會執(zhí)行成功,即需要實(shí)現(xiàn)最大努力交付。
  • Ti與 Ci需要具備冪等性

文末總結(jié)

本文主要總結(jié)了本地事務(wù)、全局事務(wù)、最終一致性等方式實(shí)現(xiàn)數(shù)據(jù)自洽。重點(diǎn)介紹了實(shí)現(xiàn)最終一致性的集中模式:可靠事件模式、TCC 模式、SAGA 模式等。數(shù)據(jù)的一致性一直是個難題,隨著微服務(wù)化之后,數(shù)據(jù)一致性更加困難,有困難不怕,只要不放棄,總會解決的。

本文轉(zhuǎn)載自微信公眾號「看山的小屋」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系看山的小屋公眾號。

 

責(zé)任編輯:武曉燕 來源: 看山的小屋
相關(guān)推薦

2023-11-22 12:55:59

微服務(wù)架構(gòu)數(shù)據(jù)庫

2019-01-15 17:58:03

微服務(wù)架構(gòu)數(shù)據(jù)

2019-12-17 08:40:33

微服務(wù)架構(gòu)數(shù)據(jù)

2023-12-27 14:23:10

微服務(wù)數(shù)據(jù)存儲

2023-06-07 08:10:29

2025-03-27 08:20:54

2024-12-26 15:01:29

2021-12-05 21:06:27

軟件

2023-09-07 08:11:24

Redis管道機(jī)制

2021-10-18 10:30:59

流計(jì)算阿里云

2021-10-13 09:55:11

流計(jì)算引擎數(shù)據(jù)

2023-12-01 13:51:21

數(shù)據(jù)一致性數(shù)據(jù)庫

2012-09-24 09:35:42

分布式系統(tǒng)

2021-12-14 07:15:57

MySQLRedis數(shù)據(jù)

2023-05-26 07:34:50

RedisMySQL緩存

2009-06-18 09:18:08

Oracle檢索數(shù)據(jù)數(shù)據(jù)一致性事務(wù)恢復(fù)

2022-02-17 21:04:27

數(shù)據(jù)庫MysqlRedis

2024-08-20 16:13:52

2022-09-15 10:37:46

MySQLRedis數(shù)據(jù)一致性

2019-09-05 08:43:34

微服務(wù)分布式一致性數(shù)據(jù)共享
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 最新超碰 | av片在线观看 | 欧美www在线| a久久 | www.蜜桃av| av看片网站 | 99久热在线精品视频观看 | 久久大香| 国产精品一区二区av | 日韩精品一区二区在线观看 | 中文字幕日韩av | 国产91视频免费 | 日韩中文字幕一区 | 国产片侵犯亲女视频播放 | 国产日韩精品久久 | 一区二区精品在线 | 日日爱夜夜操 | 亚洲精品免费视频 | 99成人精品 | 每日更新av| 一区二区免费视频 | 九九久久国产 | 做a视频| 亚洲一区二区日韩 | 国产在线色 | 激情av网站 | 中国一级特黄真人毛片免费观看 | 国产在线播放一区二区三区 | 国产成人精品免高潮在线观看 | 国产美女黄色片 | 成年人在线观看视频 | 久久久123 | 在线高清免费观看视频 | 在线看一区二区三区 | 亚洲精品一区二区三区在线观看 | 欧美日日 | 亚洲欧美在线一区 | 国产精品成人一区二区 | 日韩一区二区三区在线视频 | 成人av电影在线 | 久久综合亚洲 |