色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

全網(wǎng)最詳細(xì)的分布式一致性方案講解

jf_ro2CN3Fa ? 來(lái)源:geekhalo ? 2023-11-15 15:59 ? 次閱讀


分布式系統(tǒng)下的數(shù)據(jù)一致性可以分為兩大類(lèi):

  1. 事務(wù)一致性:當(dāng)多個(gè)節(jié)點(diǎn)進(jìn)行操作時(shí),所有節(jié)點(diǎn)最終達(dá)成的狀態(tài)都是一致的。這需要通過(guò)協(xié)調(diào)來(lái)保證操作的正確性,避免出現(xiàn)數(shù)據(jù)不一致的情況;
  2. 副本一致性:數(shù)據(jù)的多個(gè)副本之間保持一致性,這需要保證在對(duì)數(shù)據(jù)進(jìn)行修改時(shí),所有副本都能夠及時(shí)更新,避免數(shù)據(jù)出現(xiàn)不同步的情況;

定義都比較抽象,舉個(gè)例子感受一下:

1.事務(wù)一致性 :電商平臺(tái)使用優(yōu)惠券下單場(chǎng)景:

b6aa1224-838b-11ee-939d-92fbcf53809c.png
  1. 下單成功,優(yōu)惠券必須處于“已鎖定”狀態(tài);
  2. 支付成功,優(yōu)惠券必須處于“已使用”狀態(tài);
  3. 訂單取消,優(yōu)惠券需要恢復(fù)為“待使用”狀態(tài);
  4. 優(yōu)惠券和訂單間就屬于“事務(wù)一致”,兩者間存在強(qiáng)關(guān)聯(lián)關(guān)系。

2.副本一致性

  1. MySQL 主從復(fù)制:是指在主數(shù)據(jù)庫(kù)上進(jìn)行數(shù)據(jù)操作后,將這些操作同步到一個(gè)或多個(gè)從數(shù)據(jù)庫(kù)上。從庫(kù)必須與主庫(kù)保持同步,以便從庫(kù)中的數(shù)據(jù)和主庫(kù)中的數(shù)據(jù)保持一致;
  2. Redis 與 MySQL 一致性:在將 Redis 作為存儲(chǔ)使用時(shí),可以將 MySQL 看做主節(jié)點(diǎn),Redis 看做從節(jié)點(diǎn),當(dāng) MySQL 數(shù)據(jù)發(fā)生變更時(shí),自動(dòng)同步到 Redis 中,并保持?jǐn)?shù)據(jù)的一致性;
b6b8c0b2-838b-11ee-939d-92fbcf53809c.png

【注】本文著重介紹 “事務(wù)一致性”,多副本一致性,詳見(jiàn) 緩存 或 ES 篇。

1. 脫離數(shù)據(jù)庫(kù)事務(wù)的懷抱

在關(guān)系型數(shù)據(jù)庫(kù)中,事務(wù)(Transaction)是指一組數(shù)據(jù)庫(kù)操作,這些操作要么全部成功要么全部失敗。事務(wù)可以保證某些數(shù)據(jù)操作的一致性,當(dāng)某一條操作失敗時(shí),會(huì)進(jìn)行回滾,即撤銷(xiāo)已執(zhí)行的操作,使數(shù)據(jù)恢復(fù)到操作前的狀態(tài)。

提到事務(wù)一致性,不得不說(shuō)數(shù)據(jù)庫(kù)事務(wù) ACID:ACID是指數(shù)據(jù)庫(kù)事務(wù)的四個(gè)關(guān)鍵特性,分別為原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)和持久性(Durability):

  1. 原子性(Atomicity) :事務(wù)應(yīng)該被視為一個(gè)原子操作,即事務(wù)中的所有操作要么全部執(zhí)行成功,要么全部失敗回滾。如果事務(wù)執(zhí)行過(guò)程中出現(xiàn)錯(cuò)誤,所有修改操作將被回滾撤銷(xiāo),不會(huì)對(duì)數(shù)據(jù)造成損壞;
  2. 一致性(Consistency) :事務(wù)執(zhí)行前后,數(shù)據(jù)應(yīng)該保持一致?tīng)顟B(tài)。所有數(shù)據(jù)修改操作都必須確保數(shù)據(jù)庫(kù)的約束條件、觸發(fā)器等規(guī)則不會(huì)被破壞,保持?jǐn)?shù)據(jù)完整性;
  3. 隔離性(Isolation) :多個(gè)事務(wù)同時(shí)對(duì)同一數(shù)據(jù)進(jìn)行操作時(shí),事務(wù)之間應(yīng)該相互隔離,互不干擾。數(shù)據(jù)庫(kù)系統(tǒng)應(yīng)該確保在并發(fā)情況下,事務(wù)的執(zhí)行結(jié)果和串行執(zhí)行的結(jié)果一致;
  4. 持久性(Durability) :事務(wù)完成后,其對(duì)數(shù)據(jù)庫(kù)所作的所有修改都應(yīng)該被永久保存,即使系統(tǒng)崩潰或重啟后,修改的數(shù)據(jù)也應(yīng)該是可用的;

銀行轉(zhuǎn)賬應(yīng)用程序就是典型的 ACID 模型的應(yīng)用場(chǎng)景。假設(shè)用戶A要向用戶B轉(zhuǎn)賬1000元,轉(zhuǎn)賬過(guò)程就是一個(gè)事務(wù),具有原子性、一致性、隔離性和持久性四大特性:

  1. 原子性 :轉(zhuǎn)賬過(guò)程總共涉及兩個(gè)操作:從A賬戶中減去1000元,向B賬戶中加上1000元。如果這兩個(gè)操作中的任何一個(gè)失敗,整個(gè)事務(wù)都將失敗回滾;
  2. 一致性 :轉(zhuǎn)賬前后所有賬戶的余額總和應(yīng)該是不變的,不會(huì)出現(xiàn)余額不足或超額的情況;
  3. 隔離性 :如果同時(shí)發(fā)起兩個(gè)轉(zhuǎn)賬事務(wù),應(yīng)該確保每個(gè)事務(wù)只訪問(wèn)自己的數(shù)據(jù),不會(huì)互相干擾;
  4. 持久性 :一旦轉(zhuǎn)賬完成,更改數(shù)據(jù)的事務(wù)就必須寫(xiě)入磁盤(pán),保證即使系統(tǒng)崩潰或重啟后,這些數(shù)據(jù)仍然是可用的;

數(shù)據(jù)庫(kù)事務(wù)絕對(duì)是程序員的一大利器,但由于各種原因,這把利器離我們?cè)絹?lái)越遠(yuǎn):

1.負(fù)載的挑戰(zhàn):隨著業(yè)務(wù)的快速增長(zhǎng),數(shù)據(jù)庫(kù)中的數(shù)據(jù)量或負(fù)載也會(huì)達(dá)到單一實(shí)例的上線,此時(shí),我們:

  1. 垂直拆分:將不同的表放到不同的數(shù)據(jù)庫(kù)實(shí)例,比如拆分出 User 實(shí)例,Order 實(shí)例;
b6c5189e-838b-11ee-939d-92fbcf53809c.png
  1. 水平拆分:數(shù)據(jù)量超過(guò)單表最大容量時(shí),將數(shù)據(jù)分拆到不同的數(shù)據(jù)庫(kù),比如 Order-1 實(shí)例、Order-2 實(shí)例;
b6ccfb7c-838b-11ee-939d-92fbcf53809c.png
  1. 垂直+水平拆分:先進(jìn)行垂直拆分,在進(jìn)行水平拆分;
b6d74f0a-838b-11ee-939d-92fbcf53809c.png

5.微服務(wù)的挑戰(zhàn):微服務(wù)已經(jīng)成為系統(tǒng)的事實(shí)架構(gòu),特別是 Spring Boot 和 Spring Cloud 的流行:

  1. 微服務(wù)的“自治”要求每個(gè)微服務(wù)都應(yīng)該有自己的獨(dú)立數(shù)據(jù)存儲(chǔ),避免與其他服務(wù)共享數(shù)據(jù)存儲(chǔ),從而降低服務(wù)之間的耦合性;
  2. 微服務(wù)間通過(guò)服務(wù)發(fā)現(xiàn)、負(fù)載均衡等方式,將服務(wù)之間的關(guān)系解耦,從而使得每個(gè)服務(wù)都具備獨(dú)立的自治性;
b6ef81c4-838b-11ee-939d-92fbcf53809c.png

不管觸發(fā)哪一種條件,都會(huì)產(chǎn)生跨數(shù)據(jù)庫(kù)事務(wù),從而增加系統(tǒng)設(shè)計(jì)的難度。

基于 Spring Boot + MyBatis Plus + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 視頻教程:https://doc.iocoder.cn/video/

2. 常見(jiàn)一致性保障機(jī)制

針對(duì)該問(wèn)題前人已經(jīng)提出來(lái)多種應(yīng)對(duì)方案,特別是關(guān)系型數(shù)據(jù)庫(kù)。

2.1. MySQL事務(wù)一致性

熟悉 MySQL 實(shí)現(xiàn)的伙伴知道,MySQL 是通過(guò) Redo log 和 Undo log 來(lái)實(shí)現(xiàn)事務(wù)一致性的:

  1. Redo Log:Redo Log 記錄了事務(wù)對(duì)數(shù)據(jù)庫(kù)所作的修改,包括插入、更新、刪除等操作,它在事務(wù)提交前就被寫(xiě)入磁盤(pán)。如果出現(xiàn)故障導(dǎo)致系統(tǒng)崩潰,MySQL 會(huì)從 Redo Log 中恢復(fù)數(shù)據(jù);
  2. Undo Log:Undo Log 記錄了事務(wù)對(duì)數(shù)據(jù)庫(kù)所作的修改的「前置操作」,并且在事務(wù)回滾時(shí)用來(lái)撤銷(xiāo)事務(wù)所做的修改。當(dāng)事務(wù)執(zhí)行更新時(shí),MySQL 會(huì)先將修改前的數(shù)據(jù)存儲(chǔ)到 Undo Log 中,當(dāng)事務(wù)需要回滾時(shí),MySQL 會(huì)根據(jù) Undo Log 中的記錄將數(shù)據(jù)還原為修改前的狀態(tài)。

具體的如下圖所示:

b6f8f7a4-838b-11ee-939d-92fbcf53809c.png

從圖中可知:

1.每一個(gè) DML 語(yǔ)句都會(huì)為其生成對(duì)應(yīng)的 Redo log 和 Undo log。

  1. Redo log 記錄正向修改;
  2. Undo log 記錄逆向恢復(fù);

2.事務(wù)提交應(yīng)用全部 Redolog 以持久化正向修改;

3.事務(wù)回滾應(yīng)用全部 Undolog 以逆向恢復(fù);

其中,可以看出存在兩個(gè)核心流程:

  1. 向前補(bǔ)償:redo log 記錄了事務(wù)執(zhí)行的過(guò)程,以及事務(wù)提交前的數(shù)據(jù)修改,可以通過(guò)重做日志來(lái)恢復(fù)數(shù)據(jù),實(shí)現(xiàn)向前補(bǔ)償;
  2. 向后補(bǔ)償:undo log 記錄了事務(wù)執(zhí)行過(guò)程中對(duì)數(shù)據(jù)的修改,可以用于回滾事務(wù),實(shí)現(xiàn)向后補(bǔ)償;

除了兩種補(bǔ)償機(jī)制外,還涉及一個(gè)重要的組件“補(bǔ)償管理器”,用于對(duì)補(bǔ)償機(jī)制進(jìn)行統(tǒng)一協(xié)調(diào)。

2.2. 2PC 和 XA

2PC(Two-Phase Commit)和XA是分布式事務(wù)中常用的協(xié)議和接口

  1. 2PC是分布式事務(wù)協(xié)議,用于在分布式系統(tǒng)中協(xié)調(diào)多個(gè)參與者的事務(wù)提交或回滾。它包括兩個(gè)階段:準(zhǔn)備階段和提交階段,參與者在準(zhǔn)備階段告知協(xié)調(diào)者它們是否可以正常提交,如果都能正常提交,則在提交階段所有參與者都提交事務(wù)。如果有一個(gè)參與者無(wú)法正常提交,則所有參與者都需要回滾;
  2. XA是一組應(yīng)用程序接口(API),它使應(yīng)用程序能夠參與分布式事務(wù),并與事務(wù)管理器協(xié)同工作,以保證事務(wù)的一致性。XA接口包括三個(gè)接口:XA Transactions、XA Resource、XA Resource Manager,用于實(shí)現(xiàn)分布式事務(wù)的協(xié)調(diào)和管理。

MySQL 采用了兩階段提交(Two-Phase Commit,簡(jiǎn)稱(chēng) 2PC)協(xié)議,保證 Redolog 和 Binlog 間的數(shù)據(jù)一致性,確保事務(wù)在所有相關(guān)節(jié)點(diǎn)(包括 Redolog 和 Binlog)執(zhí)行的情況下,要么全部提交成功,要么全部回滾失敗。

2PC只能應(yīng)用于兩個(gè)事務(wù)參與者的場(chǎng)景,而XA可以應(yīng)用于多個(gè)事務(wù)參與者的場(chǎng)景,具體如圖所示:

b7092f34-838b-11ee-939d-92fbcf53809c.png

XA 定義了一組接口:

  1. XA資源管理器(XA Resource Manager,RM):用于管理分布式事務(wù)的資源,如數(shù)據(jù)庫(kù)、消息隊(duì)列等;
  2. XA事務(wù)管理器(XA Transaction Manager,TM):用于協(xié)調(diào)各個(gè)資源管理器的事務(wù)處理;
  3. XA接口:XA接口允許應(yīng)用程序參與到分布式事務(wù)的協(xié)調(diào)中,包括開(kāi)始、提交或回滾事務(wù)等操作;

對(duì)應(yīng)的事務(wù)提交和回滾流程如下:

  1. 應(yīng)用程序通過(guò)XA接口開(kāi)始一個(gè)分布式事務(wù),XA事務(wù)管理器為該事務(wù)分配一個(gè)唯一的全局事務(wù)ID;
  2. 應(yīng)用程序使用XA接口將某些操作注冊(cè)為分布式事務(wù)的一部分,這些操作可以涉及多個(gè)XA資源管理器;
  3. 當(dāng)應(yīng)用程序執(zhí)行到提交事務(wù)的代碼時(shí),XA事務(wù)管理器先協(xié)調(diào)各個(gè)XA資源管理器,檢查這些資源管理器是否都能夠提交事務(wù);
  4. 如果所有的資源管理器都能夠提交事務(wù),則XA事務(wù)管理器向各個(gè)資源管理器發(fā)送提交事務(wù)的請(qǐng)求,并等待它們的響應(yīng);
  5. 如果其中有任何一個(gè)資源管理器不能提交事務(wù),則XA事務(wù)管理器向各個(gè)資源管理器發(fā)送回滾事務(wù)的請(qǐng)求,并等待它們的響應(yīng);
  6. 當(dāng)所有的資源管理器都響應(yīng)提交或回滾事務(wù)的請(qǐng)求后,XA事務(wù)管理器將事務(wù)的狀態(tài)(提交或回滾)通知給應(yīng)用程序,并釋放資源。

2PC (包括升級(jí)后的 3PC),在事務(wù)執(zhí)行的整個(gè)流程中都需要對(duì)資源進(jìn)行鎖定,在分布式環(huán)境下將大幅增加系統(tǒng)響應(yīng)時(shí)間,降低整個(gè)系統(tǒng)的吞吐,在實(shí)際工作中使用的非常少。

2.3. TCC

TCC 是實(shí)現(xiàn)分布式事務(wù)解決方案的一種有效方法,更是真正應(yīng)用于實(shí)際工作的一大解決方案。

b71d833a-838b-11ee-939d-92fbcf53809c.png

TCC (try-confirm-cancel) 是一種分布式事務(wù)解決方案,它將一個(gè)分布式事務(wù)拆分成三個(gè)過(guò)程:

  1. Try 操作:嘗試執(zhí)行分布式事務(wù)中的操作,檢查所有參與方是否準(zhǔn)備好執(zhí)行事務(wù)。如果準(zhǔn)備好,則鎖定資源,等待確認(rèn)或取消操作;
  2. Confirm 操作:確認(rèn)執(zhí)行分布式事務(wù)中的操作,提交所有參與方的操作。如果有任何錯(cuò)誤,則回滾所有操作并釋放鎖定的資源;
  3. Cancel 操作:取消執(zhí)行分布式事務(wù)中的操作,回滾所有參與方的操作并釋放鎖定的資源;

TCC 的操作流程如下:

  1. 應(yīng)用程序向協(xié)調(diào)者請(qǐng)求分布式事務(wù),并傳輸所有需要執(zhí)行的操作;
  2. 協(xié)調(diào)者根據(jù) TCC 的分布式事務(wù)處理策略創(chuàng)建一個(gè)唯一的分布式事務(wù) ID,并將它分配給每個(gè)參與方;
  3. 各參與方執(zhí)行 Try 操作,并鎖定需要訪問(wèn)的資源;
  4. 協(xié)調(diào)者檢查所有參與方是否準(zhǔn)備好執(zhí)行操作,如果所有參與方都準(zhǔn)備好,則進(jìn)入 Confirm 階段;
  5. Confirm 階段中,各參與方確認(rèn)執(zhí)行操作,并將結(jié)果提交給協(xié)調(diào)者;
  6. 如果有任何錯(cuò)誤,協(xié)調(diào)者將回滾所有操作并釋放鎖定的資源。否則,所有參與方之間的事務(wù)將得到確認(rèn)執(zhí)行,釋放資源并關(guān)閉事務(wù);
  7. 如果任何參與方在 Try 階段失敗,則進(jìn)入 Cancel 階段;
  8. Cancel 階段中,各參與方撤銷(xiāo)所有操作并釋放鎖定的資源;
  9. 協(xié)調(diào)者記錄每個(gè)階段的操作,以便處理異常情況;

TCC 是一種補(bǔ)償型事務(wù)機(jī)制,通過(guò)人工干預(yù)來(lái)處理異常,本身具備極佳的靈活性,適用于各種不同類(lèi)型的應(yīng)用場(chǎng)景。

2.4. 事務(wù)一致性本質(zhì)

看了不少一致性解決方案,不知道有沒(méi)有發(fā)現(xiàn)一些規(guī)律?

核心組件基本一致:

  1. 應(yīng)用程序:簡(jiǎn)單理解為開(kāi)發(fā)的應(yīng)用系統(tǒng),借助事務(wù)管理器和資源管理的的能力,完成事務(wù)一致性保障;
  2. 事務(wù)管理器:事務(wù)的協(xié)調(diào)者,接收應(yīng)用程序的請(qǐng)求,對(duì)多個(gè)資源管理器進(jìn)行協(xié)調(diào),共同完成正向補(bǔ)償和逆向補(bǔ)償;
  3. 資源管理器:?jiǎn)我毁Y源管理者,對(duì)外提供正向補(bǔ)償接口和逆向補(bǔ)充接口,供應(yīng)用程序和事務(wù)管理器使用;

核心流程基本一致:

  1. 正向補(bǔ)償:應(yīng)用流程向前推進(jìn),最終從一個(gè)狀態(tài)變化為另一個(gè)狀態(tài);
  2. 逆向補(bǔ)償:應(yīng)用流程向后推進(jìn),將所有操作進(jìn)行回滾,使其恢復(fù)到前一狀態(tài);

簡(jiǎn)單來(lái)說(shuō):事務(wù)一致性就是通過(guò)協(xié)調(diào)各個(gè)參與節(jié)點(diǎn)來(lái)實(shí)現(xiàn)分布式事務(wù)的提交或回滾,確保所有涉及到的操作,要么全部執(zhí)行成功,要么全部不執(zhí)行。不同的實(shí)現(xiàn)方式只是不同的工具,其實(shí)現(xiàn)思路基本一致。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 實(shí)現(xiàn)的后臺(tái)管理系統(tǒng) + 用戶小程序,支持 RBAC 動(dòng)態(tài)權(quán)限、多租戶、數(shù)據(jù)權(quán)限、工作流、三方登錄、支付、短信、商城等功能

  • 項(xiàng)目地址:https://github.com/YunaiV/yudao-cloud
  • 視頻教程:https://doc.iocoder.cn/video/

3. 業(yè)務(wù)一致性保障機(jī)制

前人已經(jīng)為我們提供足夠多的工具,如何更好的使用這些工具,就需要對(duì)業(yè)務(wù)場(chǎng)景進(jìn)行深入分析。

業(yè)務(wù)系統(tǒng)一致性是指在多個(gè)系統(tǒng)或不同的環(huán)境中,不同用戶或系統(tǒng)操作所產(chǎn)生的數(shù)據(jù)在邏輯上是相同的。它的本質(zhì)是確保在任何情況下,不同系統(tǒng)或用戶產(chǎn)生的數(shù)據(jù)都是一致的,并且在系統(tǒng)中的所有操作都是以預(yù)期方式進(jìn)行的。業(yè)務(wù)系統(tǒng)一致性是確保數(shù)據(jù)的準(zhǔn)確性和可靠性的關(guān)鍵因素,可以有效地避免數(shù)據(jù)錯(cuò)誤和丟失,提高業(yè)務(wù)系統(tǒng)的可用性和可靠性,保障企業(yè)的持續(xù)發(fā)展。如下圖所示:

b72631ec-838b-11ee-939d-92fbcf53809c.png

如果可重試性事務(wù)間不存在依賴(lài)關(guān)系,可以并行執(zhí)行,具體如下:

b733ea4e-838b-11ee-939d-92fbcf53809c.png

在一個(gè)復(fù)雜的業(yè)務(wù)流程中,可以將事務(wù)分為三類(lèi):

  1. 關(guān)鍵性事務(wù):指的是系統(tǒng)中最為關(guān)鍵的一步操作,如果事務(wù)提交失敗,則進(jìn)行回滾操作;如果事務(wù)提交成功,則成為事實(shí),無(wú)法回滾;
  2. 可補(bǔ)償性事務(wù):指的是在關(guān)鍵性事務(wù)之前的事務(wù)操作,通常提供正向和逆向兩組操作,正向操作失敗或關(guān)鍵事務(wù)失敗,在會(huì)逆序調(diào)用逆向接口,以對(duì)操作進(jìn)行回滾;
  3. 可重試性事務(wù):指的是關(guān)鍵事務(wù)之后的事務(wù)操作,關(guān)鍵事務(wù)提交成功,則事實(shí)已定,下游通過(guò)重試的方式完成事務(wù);

我們以分布式系統(tǒng)中的下單流程為例:

b74ac458-838b-11ee-939d-92fbcf53809c.png
  1. 關(guān)鍵性事務(wù):就是下單操作,將用戶的信息保存到數(shù)據(jù)庫(kù)。保存失敗,對(duì)已經(jīng)操作的庫(kù)存和優(yōu)惠券進(jìn)行逆向恢復(fù);保存成功,通過(guò)重試保障下游事務(wù)的一致性;
  2. 可補(bǔ)償性事務(wù):指的是優(yōu)惠券和庫(kù)存服務(wù)提供的正向和逆向操作,正向操作可以通過(guò)逆向操作進(jìn)行恢復(fù);
  3. 可重試性事務(wù):指的是添加自動(dòng)取消任務(wù)、保存操作日志、發(fā)送 MQ,當(dāng)訂單數(shù)據(jù)保存成功后,這三者通過(guò)不斷重試保障最終都會(huì)執(zhí)行;

3.1. 關(guān)鍵性事務(wù)

關(guān)鍵性事務(wù):指在分布式系統(tǒng)中,只有當(dāng)某個(gè)事務(wù)被成功提交后,整個(gè)系統(tǒng)才能認(rèn)為這個(gè)事務(wù)是成功的。如果這個(gè)事務(wù)失敗了,那么整個(gè)系統(tǒng)就會(huì)回滾到之前的狀態(tài)。例如支付、訂單提交等。

從關(guān)鍵性事務(wù)的使用場(chǎng)景出發(fā),最適合的工具便是關(guān)系數(shù)據(jù)庫(kù)的事務(wù)保障。

b7656bdc-838b-11ee-939d-92fbcf53809c.png
  1. 事務(wù)提交成功:整個(gè)流程向前補(bǔ)償,推動(dòng)可重試性事務(wù)通過(guò)不斷重試最終完成業(yè)務(wù)邏輯;
  2. 事務(wù)提交失敗:觸發(fā)整個(gè)流程回滾,逆序調(diào)用可補(bǔ)償事務(wù)的回滾接口恢復(fù)狀態(tài);

3.2. 可補(bǔ)償事務(wù)

可補(bǔ)償事務(wù)指在某些業(yè)務(wù)操作中,如果其中一些子操作執(zhí)行失敗,可以由后續(xù)補(bǔ)償操作進(jìn)行補(bǔ)救,達(dá)到一定的業(yè)務(wù)目的,例如在資金交易中,如果賬戶余額不足而支付子操作失敗,可以通過(guò)撤銷(xiāo)訂單等補(bǔ)償操作來(lái)保障交易的正確性。

對(duì)于可補(bǔ)償事務(wù),需要提供兩組操作:

  1. 正向:標(biāo)準(zhǔn)的業(yè)務(wù)操作,比如庫(kù)存鎖定
  2. 逆向:針對(duì)正向操作的恢復(fù)操作,比如釋放鎖定庫(kù)存

3.2.1. Seata

Seata 是一個(gè)開(kāi)源的分布式事務(wù)解決方案,旨在解決分布式系統(tǒng)中的事務(wù)一致性問(wèn)題。在傳統(tǒng)的分布式系統(tǒng)中,由于各個(gè)服務(wù)之間的數(shù)據(jù)交互和操作都是獨(dú)立進(jìn)行的,因此很容易出現(xiàn)數(shù)據(jù)不一致的情況。這會(huì)導(dǎo)致系統(tǒng)出現(xiàn)各種異常情況,如數(shù)據(jù)丟失、重復(fù)提交等,從而影響系統(tǒng)的穩(wěn)定性和可靠性。

Seata 提供了多種解決方案來(lái)解決分布式事務(wù)一致性問(wèn)題。其中包括 XA 模式、TCC 模式和 SAGA 模式等。

  1. XA 模式是一種基于數(shù)據(jù)庫(kù)的事務(wù)管理模式,Seata 通過(guò)與數(shù)據(jù)庫(kù)進(jìn)行交互來(lái)實(shí)現(xiàn)分布式事務(wù)的一致性。該模式適用于對(duì)數(shù)據(jù)一致性要求比較高的業(yè)務(wù)場(chǎng)景,如金融、電商等。但是,由于需要與數(shù)據(jù)庫(kù)進(jìn)行交互,因此該模式的性能相對(duì)較低;
  2. AT模式(基于應(yīng)用層的兩階段提交方式):AT模式實(shí)現(xiàn)在應(yīng)用程序中嵌入事務(wù)語(yǔ)義,通過(guò)協(xié)調(diào)維護(hù)必要的鎖,實(shí)現(xiàn)多個(gè)業(yè)務(wù)節(jié)點(diǎn)之間跨多個(gè)數(shù)據(jù)庫(kù)表的事務(wù)。適用于關(guān)系型數(shù)據(jù)庫(kù)的應(yīng)用場(chǎng)景,如電商下單等。
  3. TCC 模式是一種基于補(bǔ)償?shù)氖聞?wù)管理模式,Seata 通過(guò)預(yù)留資源、嘗試執(zhí)行、確認(rèn)執(zhí)行和回滾執(zhí)行四個(gè)階段來(lái)實(shí)現(xiàn)分布式事務(wù)的一致性。該模式適用于對(duì)性能要求比較高的業(yè)務(wù)場(chǎng)景,如游戲、社交等。但是,由于需要進(jìn)行多次異步通信,因此該模式的復(fù)雜度較高;
  4. SAGA 模式是一種基于事件驅(qū)動(dòng)的事務(wù)管理模式,Seata 通過(guò)將一個(gè)大的分布式事務(wù)拆分成多個(gè)小的本地事務(wù),并通過(guò)異步消息傳遞來(lái)實(shí)現(xiàn)分布式事務(wù)的一致性。該模式適用于對(duì)性能和可用性要求比較高的業(yè)務(wù)場(chǎng)景,如微服務(wù)架構(gòu)下的系統(tǒng)。但是,由于需要進(jìn)行多次異步通信和狀態(tài)管理,因此該模式的復(fù)雜度也較高。

Seata 還提供了一些重要的功能,如事務(wù)日志記錄、故障恢復(fù)、動(dòng)態(tài)擴(kuò)展等,使得用戶可以更加方便地使用該框架來(lái)解決分布式事務(wù)一致性問(wèn)題。同時(shí),Seata 還具有高性能、高可用性和易用性等特點(diǎn),可以滿足各種不同場(chǎng)景下的需求。

【注】感興趣的話,可以找下 seata 的官方文檔。

3.2.2. Context + Rollback

Seata 雖好,但中間件的引入將大幅提升系統(tǒng)的復(fù)雜性,對(duì)于一些不太嚴(yán)謹(jǐn)?shù)膱?chǎng)景或者一些運(yùn)維能力不足的小團(tuán)隊(duì)可以自己實(shí)現(xiàn)回滾方案。

整體方案如下:

b776745e-838b-11ee-939d-92fbcf53809c.png
  1. 創(chuàng)建一個(gè) Context 對(duì)象,用于保存整個(gè)流程的上下文數(shù)據(jù)。其中存在一個(gè) List 屬性,維護(hù)待回滾任務(wù)列表;

  2. 每操作完一個(gè)正向流程,向 Context 中注冊(cè)一個(gè)逆向回調(diào),及 Rollback 任務(wù);

  3. 如果

  • 關(guān)鍵事務(wù)提交成功,Context 注冊(cè)的 RollbackEntry 便失去意義;
  • 關(guān)鍵事務(wù)提交失敗,調(diào)用 Context 的 fireFallback 方法進(jìn)行逆向補(bǔ)償,fireFallback 方法逆向調(diào)用注冊(cè)的回滾方法,從而恢復(fù)業(yè)務(wù)狀態(tài)

該方案基于內(nèi)存實(shí)現(xiàn),存在失靈的情況,不建議使用在嚴(yán)謹(jǐn)?shù)膱?chǎng)景。

3.3. 可重試性事務(wù)

可重試型事務(wù)指在業(yè)務(wù)操作中,如果某些操作由于網(wǎng)絡(luò)波動(dòng)等原因?qū)е率。梢酝ㄟ^(guò)重新執(zhí)行這些操作來(lái)達(dá)到其預(yù)期的結(jié)果,例如在發(fā)送短信驗(yàn)證碼時(shí),由于網(wǎng)絡(luò)狀況不佳而發(fā)送失敗,可以重新嘗試發(fā)送,直到發(fā)送成功為止。

可重試性事務(wù)沒(méi)有失敗,只有成功,哪怕是短暫的失敗也會(huì)通過(guò)不限的重試使其最終達(dá)到成功狀態(tài)。

3.3.1. @Retry

@Retry 是 Spring 框架提供的一個(gè)注解,用于在方法調(diào)用失敗時(shí)自動(dòng)進(jìn)行重試。

通過(guò) @Retry 注解,我們可以定義重試的次數(shù)、間隔時(shí)間和異常類(lèi)型等信息,從而實(shí)現(xiàn)更可靠的方法調(diào)用。

具體來(lái)說(shuō),@Retry 注解可以通過(guò)以下屬性來(lái)配置:

  1. maxAttempts:最大重試次數(shù);
  2. value:重試間隔時(shí)間的數(shù)值表示;
  3. fixedDelay:是否固定等待重試間隔時(shí)間后再進(jìn)行下一次嘗試;
  4. backoffPolicy:重試間隔時(shí)間的退避策略;
  5. allowCoreThreadTimeOut:是否允許在核心線程上進(jìn)行超時(shí)等待;
  6. excludeExceptions:需要排除的異常類(lèi)型;
  7. excludeClassNames:需要排除的類(lèi)名列表;
  8. loggerMessage:日志輸出格式;
  9. fallbackMethodName:當(dāng)所有重試都失敗后,執(zhí)行的方法名稱(chēng);

我們看下具體的使用:

  1. 基于計(jì)數(shù)器的重試實(shí)現(xiàn)
@Retryable(value={Exception.class},maxAttempts=3,backoff=@Backoff(delay=1000))
publicvoiddoSomething()throwsException{
//業(yè)務(wù)邏輯代碼
}

該實(shí)現(xiàn)會(huì)在方法調(diào)用失敗時(shí)進(jìn)行最多3次的重試,每次重試之間會(huì)等待1秒的時(shí)間。如果超過(guò)3次重試仍然失敗,則拋出異常。

  1. 基于自定義異常處理的重試實(shí)現(xiàn)
@Retryable(value={Exception.class},maxAttempts=3,backoff=@Backoff(delay=1000),fallback=@Fallback(fallbackMethod="doDefault"))
publicvoiddoSomething()throwsException{
//業(yè)務(wù)邏輯代碼
}

privateStringdoDefault(Exceptione){
//當(dāng)出現(xiàn)指定異常時(shí),執(zhí)行該方法進(jìn)行重試處理
}

該實(shí)現(xiàn)會(huì)在方法調(diào)用失敗時(shí)進(jìn)行最多3次的重試,每次重試之間會(huì)等待1秒的時(shí)間。如果超過(guò)3次重試仍然失敗,則會(huì)執(zhí)行 doDefault 方法來(lái)進(jìn)行重試處理。在該方法中,我們可以自定義處理方式來(lái)處理異常情況。

@Retry 仍舊是一個(gè)內(nèi)存解決方案,在極端場(chǎng)景下可能出現(xiàn)任務(wù)丟失的情況。因此在實(shí)際工作中,很少用于可重試性事務(wù)這種場(chǎng)景。

3.3.2. MQ

MQ(消息隊(duì)列)消費(fèi)者重試機(jī)制是指在消費(fèi)消息時(shí),如果消費(fèi)者無(wú)法成功消費(fèi)消息(比如網(wǎng)絡(luò)異常、服務(wù)器故障等原因),會(huì)自動(dòng)重試一定次數(shù)或間隔一定時(shí)間后再次嘗試消費(fèi)消息,以保證消息的可靠性和可用性。

如下圖所示:

b78639b6-838b-11ee-939d-92fbcf53809c.png

具有MQ的可重試性事務(wù),需要以下保障:

  1. 保障業(yè)務(wù)操作與消費(fèi)發(fā)送之間的一致性:業(yè)務(wù)操作成功,消息必須發(fā)送成功;業(yè)務(wù)操作失敗,消息不能發(fā)送;
  2. 保障消息投遞和消費(fèi)消費(fèi)之間的一致性:對(duì)于消費(fèi)失敗的消息,MQ 會(huì)自動(dòng)進(jìn)行重試,直至消費(fèi)成功;

一般情況下會(huì)采用多次投遞的方式來(lái)實(shí)現(xiàn)消息投遞和消息消費(fèi)之間的一致性,所以消息消費(fèi)者需要保障冪等性,避免多次投遞造成的業(yè)務(wù)問(wèn)題。

3.3.2.1. 半消息

RocketMQ事務(wù)消息是一種支持分布式事務(wù)的消息模型,將消息生產(chǎn)和消費(fèi)與業(yè)務(wù)邏輯綁定在一起,確保消息發(fā)送和事務(wù)執(zhí)行的原子性,保證消息的可靠性。

事務(wù)消息分為兩個(gè)階段:發(fā)送消息和確認(rèn)消息,確認(rèn)消息分為提交和回滾兩個(gè)操作。在提交操作執(zhí)行完畢后,消息才會(huì)被消費(fèi)端消費(fèi),而在回滾操作執(zhí)行完畢后,消息會(huì)被刪除,從而達(dá)到了事務(wù)的一致性和可靠性。

事務(wù)消息的發(fā)生流程如下:

b791614c-838b-11ee-939d-92fbcf53809c.png
  1. 生產(chǎn)者發(fā)送prepare消息到RocketMQ服務(wù)端,RocketMQ將消息存儲(chǔ)到本地并返回結(jié)果;
  2. 生產(chǎn)者開(kāi)始執(zhí)行本地事務(wù),并根據(jù)本地事務(wù)的結(jié)果將狀態(tài)信息提交給RocketMQ服務(wù)端;
  3. 如果本地事務(wù)執(zhí)行成功,生產(chǎn)者向RocketMQ服務(wù)端發(fā)送commit消息;
  4. 如果本地事務(wù)執(zhí)行失敗,生產(chǎn)者向RocketMQ服務(wù)端發(fā)送rollback消息;
  5. RocketMQ接收到commit或rollback消息后,對(duì)消息進(jìn)行投放或刪除;

如果生成者發(fā)送 prepare 消息后,未在規(guī)定時(shí)間內(nèi)發(fā)送 commit 或 rollback 消息,RocketMQ 將進(jìn)入恢復(fù)流程,具體如下:

b7a69fd0-838b-11ee-939d-92fbcf53809c.png
  1. 如果在回查的時(shí)間之前沒(méi)有收到相應(yīng)的 commit 或 rollback 消息,則 RocketMQ 會(huì)將對(duì)該 prepare 消息進(jìn)行回查;
  2. 應(yīng)用程序接收到回查指令,從業(yè)務(wù)庫(kù)中獲取數(shù)據(jù),并根據(jù)業(yè)務(wù)邏輯進(jìn)行判斷,最終是 commit 還是 rollback;
  3. RocketMQ 接收到 commit 或 rollback 回復(fù)后,進(jìn)行相應(yīng)動(dòng)作,從而實(shí)現(xiàn)業(yè)務(wù)操作和消息發(fā)送的一致性;

使用 RocketMQ 的事務(wù)消息代碼示例如下:

//編寫(xiě)事務(wù)監(jiān)聽(tīng)器類(lèi)
publicclassTransactionListenerImplimplementsTransactionListener{
privateAtomicIntegertransactionIndex=newAtomicInteger(0);

//執(zhí)行本地事務(wù)
publicLocalTransactionStateexecuteLocalTransaction(Messagemsg,Objectarg){
intvalue=transactionIndex.getAndIncrement();
System.out.println("executeLocalTransaction"+value);
//TODO執(zhí)行本地事務(wù),并返回事務(wù)狀態(tài)
//本例假定index為偶數(shù)的消息執(zhí)行成功,奇數(shù)的消息執(zhí)行失敗
if(value%2==0){
returnLocalTransactionState.COMMIT_MESSAGE;
}
returnLocalTransactionState.ROLLBACK_MESSAGE;
}

//檢查本地事務(wù)狀態(tài)
publicLocalTransactionStatecheckLocalTransaction(MessageExtmsg){
System.out.println("checkLocalTransaction"+msg.getTransactionId());
//模擬檢查本地事務(wù)狀態(tài),返回事務(wù)狀態(tài)
booleancommitted=prepare(true);
if(committed){
returnLocalTransactionState.COMMIT_MESSAGE;
}
returnLocalTransactionState.UNKNOW;
}

//模擬操作預(yù)處理邏輯
privatebooleanprepare(booleancommit){
System.out.println("prepare"+(commit?"commit":"rollback"));
returncommit;
}

}

//編寫(xiě)發(fā)送消息的代碼
publicclassProducer{
privatestaticfinalStringNAME_SERVER_ADDR="localhost:9876";

publicstaticvoidmain(String[]args)throwsException{
TransactionMQProducerproducer=newTransactionMQProducer("MyGroup");
producer.setNamesrvAddr(NAME_SERVER_ADDR);
//注冊(cè)事務(wù)監(jiān)聽(tīng)器
producer.setTransactionListener(newTransactionListenerImpl());
producer.start();

//發(fā)送事務(wù)消息
String[]tags={"TagA","TagB","TagC"};
for(inti=0;i3;i++){
Messagemsg=newMessage("TopicTest",tags[i],("HelloRocketMQ"+i).getBytes(StandardCharsets.UTF_8));
//在消息發(fā)送時(shí)傳遞給事務(wù)監(jiān)聽(tīng)器的參數(shù)
SendResultsendResult=producer.sendMessageInTransaction(msg,null);
System.out.printf("%s%n",sendResult);
}

//關(guān)閉生產(chǎn)者
producer.shutdown();
}
}

單看代碼很難理解,簡(jiǎn)單畫(huà)了張圖,具體如下:

b7b6e836-838b-11ee-939d-92fbcf53809c.png

其核心部分就是 TransactionListener 實(shí)現(xiàn),其他部分與正常的消息發(fā)送基本一致,TransactionListener 主要完成:

  1. 執(zhí)行本地事務(wù),也就是業(yè)務(wù)操作;
  2. 執(zhí)行結(jié)果檢測(cè),通過(guò)反查業(yè)務(wù)數(shù)據(jù),決定消息的后續(xù)處理策略;

為了使用事務(wù)消息,我們不得不在TransactionListener中編寫(xiě)進(jìn)行大量的適配邏輯,增加研發(fā)成本,同時(shí)由于邏輯被拆分到多處,也增加了代碼的理解成本。

事務(wù)消息存在一定的問(wèn)題:

  1. 與 MQ 實(shí)現(xiàn)強(qiáng)相關(guān),并不是每個(gè) MQ 實(shí)現(xiàn)都對(duì)事務(wù)消息提供支持;
  2. API 比較晦澀,存在一定的學(xué)習(xí)成本,同時(shí)需要對(duì)業(yè)務(wù)邏輯拆分到 Listener 中,增加理解成本;

有沒(méi)有實(shí)用性強(qiáng)、使用簡(jiǎn)單的方案,那可以使用 事務(wù)消息表 方案。

3.3.2.2. 事務(wù)消息表

事務(wù)消息表方案是一種常用的保證消息發(fā)送與業(yè)務(wù)操作一致性的方法。該方案基于數(shù)據(jù)庫(kù)事務(wù)和消息隊(duì)列,將消息發(fā)送和業(yè)務(wù)操作放入同一個(gè)事務(wù)中,并將業(yè)務(wù)操作和消息發(fā)送的狀態(tài)記錄在數(shù)據(jù)庫(kù)的消息表中,以實(shí)現(xiàn)消息的可靠性和冪等性。

如下圖所示:

b7c5be92-838b-11ee-939d-92fbcf53809c.png

核心流程如下:

  1. 應(yīng)用程序開(kāi)啟一個(gè)數(shù)據(jù)庫(kù)事務(wù),并在事務(wù)中執(zhí)行業(yè)務(wù)操作和消息發(fā)送;
  2. 在事務(wù)中,將業(yè)務(wù)操作和消息發(fā)送的狀態(tài)記錄到消息表中;
  3. 如果業(yè)務(wù)操作執(zhí)行成功,并且消息發(fā)送成功,提交事務(wù),否則回滾事務(wù);
  4. 定時(shí)掃描消息表,并根據(jù)消息狀態(tài)重新發(fā)送未被確認(rèn)的消息。如果消息發(fā)送成功,更新消息狀態(tài);否則根據(jù)重試次數(shù)更新消息狀態(tài)或者丟棄消息;

通過(guò)事務(wù)消息表方案,可以保證消息的可靠性和冪等性。即使在消息發(fā)送失敗或應(yīng)用程序崩潰的情況下,也可以通過(guò)重新發(fā)送消息將業(yè)務(wù)操作和消息發(fā)送的狀態(tài)同步。同時(shí),該方案可以避免消息重復(fù)發(fā)送和漏發(fā)的情況。

作為一種通用解決方案,lego 對(duì)其進(jìn)行支持,可參考 reliable-message 模塊。

4. 業(yè)務(wù)補(bǔ)償

不管在設(shè)計(jì)時(shí)使用哪種方案,都是在盡力降低不一致出現(xiàn)的概率,但可怕的是不一致問(wèn)題終究會(huì)發(fā)生。

是不是有些奇怪,做了這么多還是無(wú)法從根源上徹底解決一致性問(wèn)題,在實(shí)際工作中就是這樣:

  1. 并不是所有的可補(bǔ)償事務(wù)都能回滾成功:在正向流程中我們都會(huì)對(duì)資源進(jìn)行鎖定,如果其他操作破壞了鎖定資源或者破壞了準(zhǔn)入條件,程序?qū)o(wú)法正常回滾,必須人工介入進(jìn)行解決。比如,生單時(shí)成功鎖定優(yōu)惠券,但超管發(fā)現(xiàn)優(yōu)惠券發(fā)放錯(cuò)誤對(duì)其進(jìn)行回收,在進(jìn)行優(yōu)惠券回滾時(shí),由于優(yōu)惠券處于不可用狀態(tài),導(dǎo)致無(wú)法正常回滾;
  2. 并不是所有的可重試事務(wù)都能重試成功:業(yè)務(wù)執(zhí)行到可重試事務(wù),只能證明其滿足關(guān)鍵事務(wù)之前的條件,并不一定滿足下游可重試事務(wù)的條件。比如,支付成功后需要給用戶發(fā)送微信消息,但用戶授權(quán)信息已經(jīng)過(guò)期導(dǎo)致消息無(wú)法發(fā)送;
  3. 業(yè)務(wù)迭代引入 bug 會(huì)破壞事務(wù)機(jī)制:這個(gè)就更常見(jiàn)了,由于bug導(dǎo)致流程錯(cuò)誤,不得不修復(fù)問(wèn)題和數(shù)據(jù)

除了主動(dòng)降低不一致性概率,還需要添加一些被動(dòng)保護(hù)機(jī)制,也就是常說(shuō)的業(yè)務(wù)補(bǔ)償。

4.1. 查詢模式

查詢模型是最常用的一種方式,主要用于應(yīng)對(duì)網(wǎng)絡(luò)傳輸中的第三態(tài)問(wèn)題。

第三態(tài)指的是在分布式系統(tǒng)中,在進(jìn)行跨網(wǎng)絡(luò)調(diào)用時(shí),調(diào)用方無(wú)法確定被調(diào)用方的狀態(tài)是否改變了,因?yàn)檫@兩者之間存在一段未知而不可控的網(wǎng)絡(luò)延遲時(shí)間,導(dǎo)致調(diào)用方無(wú)法立即得到被調(diào)用方的結(jié)果。這種情況下,第三態(tài)可以看做是一個(gè)未知的狀態(tài),需要通過(guò)一些機(jī)制來(lái)解決這個(gè)問(wèn)題。

b7d9d7ba-838b-11ee-939d-92fbcf53809c.png

當(dāng)網(wǎng)絡(luò)調(diào)用出現(xiàn)第三態(tài)時(shí),最簡(jiǎn)單的方式便是對(duì)不確定的狀態(tài)進(jìn)行查詢,如上圖所示:

  1. 調(diào)用方調(diào)用服務(wù)完成業(yè)務(wù)操作,如果成功拿到執(zhí)行結(jié)果,則直接進(jìn)行后續(xù)流程;

  2. 如果發(fā)生網(wǎng)絡(luò)超時(shí),將通過(guò)狀態(tài)查詢接口來(lái)檢查之前的操作是否完成,如果:

  • 已完成,則繼續(xù)執(zhí)行后續(xù)流程;
  • 未完成,在重新發(fā)起業(yè)務(wù)調(diào)用;

RocketMQ 的事務(wù)消息便是基于該機(jī)制進(jìn)行實(shí)現(xiàn)。

4.2. 任務(wù)檢測(cè)模式

當(dāng)一個(gè)業(yè)務(wù)操作完成后,需要處理多個(gè)后續(xù)任務(wù),為了保障所有任務(wù)都會(huì)被執(zhí)行,可以使用該模式。

如下圖所示:

b7eb25d8-838b-11ee-939d-92fbcf53809c.png
  1. 業(yè)務(wù)操作后,將業(yè)務(wù)變更和檢測(cè)任務(wù)在同一事務(wù)保護(hù)下進(jìn)行入庫(kù);

  2. 系統(tǒng)繼續(xù)執(zhí)行后續(xù)任務(wù),執(zhí)行完成后對(duì)任務(wù)狀態(tài)進(jìn)行更新;

  3. 系統(tǒng)周期性對(duì)超時(shí)未執(zhí)行的任務(wù)進(jìn)行加載,并進(jìn)行檢測(cè),如果

  • 已經(jīng)執(zhí)行,則更新任務(wù)狀態(tài)
  • 如果未執(zhí)行,則觸發(fā)任務(wù)執(zhí)行

本地消息表就是基于該模式進(jìn)行構(gòu)建。

4.3. 對(duì)賬模式

對(duì)賬模式經(jīng)常出現(xiàn)在與銀行等金融機(jī)構(gòu)對(duì)接的場(chǎng)景。

b7f79eda-838b-11ee-939d-92fbcf53809c.png

業(yè)務(wù)對(duì)賬思路非常簡(jiǎn)單:

  1. 從不同的業(yè)務(wù)系統(tǒng)獲取對(duì)賬數(shù)據(jù);

  2. 按照規(guī)則進(jìn)行雙向?qū)~,如果

  • 一致,則說(shuō)明系統(tǒng)一致
  • 不一致,進(jìn)行報(bào)警,人工介入進(jìn)行處理

必須是雙向?qū)~,單向?qū)~會(huì)出現(xiàn)數(shù)據(jù)丟失情況。

5. 小結(jié)

一致性是分布式系統(tǒng)面臨的巨大挑戰(zhàn),根據(jù)不同場(chǎng)景可以將一致性分為:

  1. 事務(wù)一致性。在一個(gè)事務(wù)內(nèi)的所有操作,要么全部完成,要么全部不完成,即保證這些操作是對(duì)數(shù)據(jù)的一致更新,避免數(shù)據(jù)出現(xiàn)不一致的情況。主要通過(guò)使用事務(wù)保證來(lái)實(shí)現(xiàn),例如:關(guān)系型數(shù)據(jù)庫(kù)的ACID事務(wù)。
  2. 副本一致性。各個(gè)副本之間的數(shù)據(jù)保持一致。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),需要將這個(gè)變化同步到所有的副本中。主要使用副本同步技術(shù)來(lái)實(shí)現(xiàn),例如MySQL的主從復(fù)制、MySQL 到 Redis的數(shù)據(jù)同步;

本文重點(diǎn)對(duì)事務(wù)一致性進(jìn)行全方位的闡述,包括:

1.技術(shù)視角,常見(jiàn)的解決方案:

  1. MySQL 實(shí)現(xiàn)
  2. 2PC和XA協(xié)議
  3. TCC 解決方案

2.業(yè)務(wù)視角,將不同的事務(wù)進(jìn)行分類(lèi),以便更好的解決:

  1. 關(guān)鍵事務(wù)
  2. 可補(bǔ)償性事務(wù)
  3. 可重試性事務(wù)

有了這些方案后,很多場(chǎng)景下仍需落地業(yè)務(wù)補(bǔ)充,常見(jiàn)方案包括:

  1. 查詢模型
  2. 任務(wù)檢查模式
  3. 對(duì)賬模型

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 磁盤(pán)
    +關(guān)注

    關(guān)注

    1

    文章

    380

    瀏覽量

    25242
  • 數(shù)據(jù)庫(kù)
    +關(guān)注

    關(guān)注

    7

    文章

    3845

    瀏覽量

    64584
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    829

    瀏覽量

    26670

原文標(biāo)題:全網(wǎng)最詳細(xì)的分布式一致性方案講解(徹底搞懂)

文章出處:【微信號(hào):芋道源碼,微信公眾號(hào):芋道源碼】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    行代碼,保障分布式事務(wù)一致性—GTS:微服務(wù)架構(gòu)下分布式事務(wù)解決方案

    解決方案----GTS。該方案中提到的GTS是目前業(yè)界第款,也是唯款通用的解決微服務(wù)分布式
    發(fā)表于 06-05 19:14

    一致性規(guī)劃研究

    針對(duì)一致性規(guī)劃的高度求解復(fù)雜度,分析主流一致性規(guī)劃器的求解策略,給出影響一致性規(guī)劃器性能的主要因素:?jiǎn)l(fā)信息的有效,信念狀態(tài)表示方法的緊湊
    發(fā)表于 04-06 08:43 ?12次下載

    藍(lán)鯨集群文件系統(tǒng)中資源交互一致性協(xié)議

    在藍(lán)鯨集群文件系統(tǒng)中,分布式資源交互在系統(tǒng)異常的情況下會(huì)出現(xiàn)資源狀態(tài)不一致的情況,為解決這問(wèn)題,該文提出分布式資源交互一致性協(xié)議S2PC-
    發(fā)表于 04-21 09:24 ?12次下載

    DBA迅速解決分布式事務(wù)XA一致性問(wèn)題

    DBA迅速解決分布式事務(wù)XA一致性問(wèn)題
    發(fā)表于 09-07 14:45 ?3次下載
    DBA迅速解決<b class='flag-5'>分布式</b>事務(wù)XA<b class='flag-5'>一致性</b>問(wèn)題

    分布式事務(wù)控制的原理實(shí)例分析

    八仙過(guò)海各顯神通。以下是我對(duì)分布式事務(wù)控制的理解: 分布式事務(wù)控制的最終目標(biāo)是實(shí)現(xiàn)一致性方案大體分為實(shí)時(shí)一致性和最終
    發(fā)表于 09-28 19:04 ?0次下載
    <b class='flag-5'>分布式</b>事務(wù)控制的原理實(shí)例分析

    分布式一致性算法Yac

    傳統(tǒng)靜態(tài)拓?fù)渲鲝哪P?b class='flag-5'>分布式一致性算法存在嚴(yán)重負(fù)載不均及單點(diǎn)性能瓶頸效應(yīng),且崩潰節(jié)點(diǎn)大于集群規(guī)模的50qo時(shí)算法無(wú)法正常工作。針對(duì)上述問(wèn)題,提出基于動(dòng)態(tài)拓?fù)浼坝邢薇頉Q思想的分布式一致性
    發(fā)表于 11-27 17:49 ?0次下載
    <b class='flag-5'>分布式</b><b class='flag-5'>一致性</b>算法Yac

    基于消息通信的分布式系統(tǒng)最終一致性平臺(tái)

    分布式系統(tǒng)中為了滿足高性能和吞吐量,般采用異步消息通信方式,但消息通信沒(méi)有解決分布式事務(wù)不一致問(wèn)題。針對(duì)這個(gè)問(wèn)題,提出建立一致性保障平臺(tái)
    發(fā)表于 12-04 16:15 ?0次下載
    基于消息通信的<b class='flag-5'>分布式</b>系統(tǒng)最終<b class='flag-5'>一致性</b>平臺(tái)

    分布式大數(shù)據(jù)不一致性檢測(cè)

    不高;而分布式環(huán)境下不一致性檢測(cè)更富有挑戰(zhàn),不僅需要考慮數(shù)據(jù)的遷移,檢測(cè)任務(wù)如何分配也是個(gè)難題.在大數(shù)據(jù)背景下,上述問(wèn)題更加突出.提出了
    發(fā)表于 01-12 16:29 ?0次下載

    一致性哈希是什么?為什么它是可擴(kuò)展的分布式系統(tǒng)架構(gòu)的個(gè)必要工具

    在本文中,我們將了解一致性哈希是什么、為什么它是可擴(kuò)展的分布式系統(tǒng)架構(gòu)中的個(gè)必要工具。
    的頭像 發(fā)表于 07-17 17:57 ?4415次閱讀

    基于自觸發(fā)一致性算法的分布式分層控制策略

    針對(duì)傳統(tǒng)下垂控制及線路阻抗不匹配等因素引起的孤島微電網(wǎng)電壓偏差及無(wú)功功率難以均分的問(wèn)題,提出基于自觸發(fā)一致性算法的分布式分層控制策略。在微電網(wǎng)二次控制層采用一致性算法構(gòu)造電壓、無(wú)功功率全局平均值估計(jì)
    發(fā)表于 03-24 15:35 ?9次下載
    基于自觸發(fā)<b class='flag-5'>一致性</b>算法的<b class='flag-5'>分布式</b>分層控制策略

    種更安全的分布式一致性算法選舉機(jī)制

    目前應(yīng)用于分布式系統(tǒng)中的基于選舉的分布式一致性算法(類(lèi) Paxos算法),都是采用得到50%以上選票者當(dāng)選 Leader的方式進(jìn)行選舉。此種選舉機(jī)制類(lèi)似現(xiàn)實(shí)生活中的選舉,存在因控制投票而喪失系統(tǒng)去
    發(fā)表于 04-07 10:29 ?9次下載
    <b class='flag-5'>一</b>種更安全的<b class='flag-5'>分布式</b><b class='flag-5'>一致性</b>算法選舉機(jī)制

    最終一致性是現(xiàn)在大部分高可用的分布式系統(tǒng)的核心思路

    這篇文章我們聊分布式相關(guān)的內(nèi)容。 提到分布式系統(tǒng),就定繞不開(kāi)“一致性”,這次我們說(shuō)說(shuō):最終一致性。 最終
    的頭像 發(fā)表于 06-17 14:40 ?1906次閱讀

    為什么需要分布式共識(shí)算法

    滿足CAP理論,而 分布式共識(shí)算法解決的就是CAP理論中的一致性問(wèn)題。整個(gè)一致性問(wèn)題分為三種問(wèn)題: 順序一致性 線性一致性 因果
    的頭像 發(fā)表于 11-10 10:18 ?605次閱讀
    為什么需要<b class='flag-5'>分布式</b>共識(shí)算法

    分布式系統(tǒng)中常見(jiàn)的一致性模型

    什么是一致性模型? 在分布式系統(tǒng)中,C(一致性) 和 A(可用)始終存在矛盾。若想保證可用,就必須通過(guò)復(fù)制、分片等方式冗余存儲(chǔ)。而
    的頭像 發(fā)表于 11-10 11:33 ?973次閱讀
    <b class='flag-5'>分布式</b>系統(tǒng)中常見(jiàn)的<b class='flag-5'>一致性</b>模型

    分布式智慧終端:挑戰(zhàn)與解決方案

    分布式智慧終端在應(yīng)用中面臨多種挑戰(zhàn),以下是其中些關(guān)鍵的挑戰(zhàn)以及可能的解決方案: 數(shù)據(jù)一致性挑戰(zhàn) :在分布式系統(tǒng)中,數(shù)據(jù)的
    的頭像 發(fā)表于 01-24 14:50 ?468次閱讀
    主站蜘蛛池模板: 大睾丸内射老师| 亚洲精品视频免费| 一本色道久久综合亚洲精品 | 俄罗斯女人与马Z00Z视频| 久久视频精品38在线播放| 天堂网久久| 操他射他影院| 男女免费观看在线爽爽爽视频 | 久久天天躁狠狠躁夜夜呲| 亚洲乱妇88网| 国产精品久久一区二区三区蜜桃 | 国产精品毛片AV久久97| 日操夜操天天操| CHRISTMAS农村夫妻HO| 久久影院毛片一区二区| 亚洲欧美激情精品一区二区| 国产国语在线播放视频| 日本撒尿特写| yellow日本动漫高清| 免费久久狼人香蕉网| 在线观看日本免费| 九九在线精品视频| 亚洲精品无码一区二区三区四虎| 国产精品18久久久久网站 | ppypp午夜限制不卡影院私人| 麻豆E奶女教师国产精品| 有人在线观看的视频吗免费| 吉吉影音先锋av资源网| 亚洲精品动漫免费二区| 国产亚洲福利在线视频| 特黄特色大片免费播放器试看| 成人性生交大片免费看中文| 青青草国产偷拍在线av| ppypp午夜限制不卡影院私人| 欧美16一17sex性hd| 99久久久无码国产AAA精品| 蜜芽资源高清在线观看| 2021国产精品视频| 蜜桃狠狠色伊人亚洲综合网站| [高清无码] 波多野结衣| 扒开老师大腿猛进AAA片邪恶|