認識分佈式事務

  • 什麼是事務

事務基本理論:

1、從數據庫的角度(對數據庫來說): 一個 SQL 語句就是一個事務

2、從業務角度: 一個程序實現單元就是一個事務(一條或多個 SQL 組成)

事務特性:ACID 事務特性

1、原子性: 要麼都成功,要麼都失敗

2、一致性: 事務開啟之前對其他線程可見的狀態,中間狀態不可見,事務結束之後才可見。

3、隔離性: 事務與事務之間隔離的 (底層使用鎖)

4、持久性: 把數據存儲在磁盤

開發業務: 一般情況下,都使用本地事務(沒有解決分佈式事務)

如下:本地事務,單機事務 一個事務單元

認識分佈式事務

特點: 應用程序操作的是單一的數據源,讓多個操作是一個原子性操作。

思考問題

項目都使用分佈式架構的模式,數據一致性處理非常困難???

1、網絡抖動

2、網絡延遲

3、服務宕機(無法避免)

4、機器宕機

5、程序崩潰

6、異常異常

………………….

以上問題是必然會發生的,因此解決數據一致性問題才會如此困難? ---- 在處理數據一致

性的問題上面,必須有所取捨 ----

強一致性(基於數據庫) ----- CAP 理論(分佈式)----- Base 理論(最終一致性)

  • CAP

在當前的軟件架構模式下,有狀態服務部署(分佈式部署模式下),無法同時保證可用性,

和一致性,必須有所取捨。

如果我們保證一致性,會存在分區的問題。

如果追求一致性:可讓數據完成同步後,大家在去讀去數據,損失一部分性能,換取一致性。

如果追求可用性:可以採用異步模式同步數據,只有主機進行讀操作,從機負責備份,監控主機,切換master,切換這一瞬間,從機是沒有主機部分數據的,因此會存在數據的丟失。

在互聯網項目,追求性能上提升,因此選擇可用性,提升項目性能。但是選擇可用性後,數據一致性會存在問題。如何解決呢??

  • Base 理論

BASE 是 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent(最終一致性)三個短語的縮寫。

基本可用(Basically Available)指分佈式系統在出現不可預知故障的時候,允許損失部分可用性。

軟狀態( Soft State)指允許系統中的數據存在中間狀態,並認為該中間狀態的存在不會影響系統的整體可用性。

最終一致( Eventual Consistency)強調的是所有的數據更新操作,在經過一段時間的同步之後,最終都能夠達到一個一致的狀態

解決方案:

最大努力通知(非可靠消息、定期校對)

可靠消息最終一致性(異步確保

TCC(兩階段型、補償型)

  • 分佈式事務場景

分佈事務基本定義:

當下互聯網絕大部分公司都進行了數據庫拆分和服務化(SOA),微服務。在這種情況下,完成某一個業務功能可能需要橫跨多個服務,操作多個數據庫。

這就涉及到到了分佈式事務,用需要操作的資源位於多個資源服務器上,而應用需要保證對於多個資源服務器的數據的操作,要麼全部成功,要麼全部失敗。本質上來說,分佈式事務就是為了保證不同資源服務器的數據一致性

從分佈式架構層面對分佈式事務進行分析:

認識分佈式事務

注意: 以上架構把一個事務單元拆分為多個子事務(微服務架構拆分),以上每一個子事務都屬於一個業務動作,在業務需求來說,要求這些業務動作要麼都成功,要麼都失敗。也就是說要求這 4 個事務,要麼都成功,要麼都失敗。

總結: 所謂的分佈式事務,其實就是保證多個子事務要麼都成功,要麼都失敗;

問: 以下的場景,是否屬於分佈式事務的場景???

場景 1:一個應用程序操作多個庫(redis,mysql,es,mq………..)

認識分佈式事務

以上也屬於分佈式事務場景,解決 Redis,mysql 數據一致性的問題。使用本地事務,只能控制 MySQL 數據一致性 ,不能控制 Redis 數據一致性。因此 Redis mysql 如果存在業務的關聯性,必須保證 Redis,mysql 數據一致性。

場景 2: 應用程序操作的多個數據源,是否屬於分佈式事務?

認識分佈式事務

以上的操作方式,是操作多個數據源(事務本質:數據庫的事務),因此 datasource1,datasource2

屬於不同的事務,這個 2 個事務相互沒有感知,因此這 2 個事務屬於隔離的狀態,是屬於不同進程的事務。因此這個屬於分佈式事務。

如何解決分佈式事務?

感知:

1、感知不同服務事務狀態,如果每一個服務事務都準備好了,統一通知大家一起提交。

2、業務補償機制

  • 分佈式事務規範
  1. X/OPEN 事務模型

1)應用程序(Application Program : AP): 定義事務邊界(事務開始,結束)--- @Transactional @分佈式事務註解

2)資源管理器 (Resource Manager: RM):任何用來存儲數據的服務

3)事務管理器(Transaction Manager : TM): 監控事務進度,負責事務提交,回滾 ---TransactionManager

4)通信資源管理(Communcation Resource Manager : CRM)

5) 通信協議 (負責事務模型之間的通信協議)

認識分佈式事務

X/open 組織把分佈式事務處理模型抽象成了上圖所示:AP,TM,RM 三者之間關係。

分佈式模式下: 微服務架構:鏈式調用 --- 存在如下的分佈式事務模型 --- 全局事務樹模

TM: 存在形式是什麼???

1)jar ----- 和應用程序集成在一起

2)服務形式 --- 第三方單獨部署

2. Xa接口規範

認識分佈式事務

XA:定義了TM和RM交互接口規範【事務註冊、提交、回滾、事務結束.....】

XA標準:存儲的數據的服務都開放了支持分佈式事務接口規範 XA(MYSQL 、ORACLE)

TM 事務管理器也必須遵循XA的規範來調用事務控制器接口

x/open 組織制定 TM/RM 接口交互規範,用來處理分佈式事務。

1)xa_reg 註冊事務

2)xa_start 開啟事務

3)xa_close 關閉事務

……………………………………………………………..

思考: 如何沒有接口規範,會發生什麼???

RM(存儲數據的服務)

1)MYSQL

2)Oracle

3)SQL server

4)mq

TM (事務管理器)-- 廠商開發了很多事務管理器

XA 接口規範制定後:

Mysql5.7 實現 xa 接口規範,支持分佈式事務

Rocketmq 集成 xa 接口規範

數據庫分佈式支持:

認識分佈式事務

3、2pc

兩階段提交協議(Two Phase Commit),XA 規範對其進行了優化。而從字面意思來理解,Two Phase Commit,就是將提交(commit)過程劃分為 2 個階段(Phase):


認識分佈式事務

應用程序: 只需要定義事務邊界即可,一切事務執行,提交,回滾都交給 TM存在問題:

1、阻塞問題: TM 宕機,事務已經執行(上鎖),一直處於阻塞狀態,無法釋放。

2、數據一致性問題

Commit 階段,RM1 已經提交,RM1 由於網絡的原因,沒有送達提交信息,出現RM1,RM2 數據不一致的問題。

4、3pc

三階段提交(3PC)[Three-phase commit],是二階段提交(2PC)的改進版本。與兩階段提交不同的是,三階段提交有兩個改動點

- 引入超時機制。同時在協調者和參與者中都引入超時機制。

- 在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段之前各參與節點的狀態是一致的。也就是說,除了引入超時機制之外,3PC 把 2PC 的準備階段再次一分為二,這樣三階段提交就有 CanCommit、PreCommit、DoCommit 三個階段

認識分佈式事務

CanCommit階段

3PC的CanCommit階段其實和2PC的準備階段很像。協調者向參與者發送commit請求,參與者如果可以提交就返回Yes響應,否則返回No響應。

  • 事務詢問

    協調者向參與者發送CanCommit請求。詢問是否可以執行事務提交操作。然後開始等待參與者的響應。

  • 響應反饋 參與者接到CanCommit請求之後,正常情況下,如果其自身認為可以順利執行事務,則返回Yes響應,並進入預備狀態。否則反饋No

PreCommit階段

協調者根據參與者的反應情況來決定是否可以記性事務的PreCommit操作。根據響應情況,有以下兩種可能。

假如協調者從所有的參與者獲得的反饋都是Yes響應,那麼就會執行事務的預執行。

  • 發送預提交請求 協調者向參與者發送PreCommit請求,並進入Prepared階段。

  • 事務預提交 參與者接收到PreCommit請求後,會執行事務操作,並將undo和redo信息記錄到事務日誌中。

  • 響應反饋 如果參與者成功的執行了事務操作,則返回ACK響應,同時開始等待最終指令。

doCommit階段

該階段進行真正的事務提交,也可以分為以下兩種情況。

執行提交

  • 發送提交請求 協調接收到參與者發送的ACK響應,那麼他將從預提交狀態進入到提交狀態。並向所有參與者發送doCommit請求。

  • 事務提交 參與者接收到doCommit請求之後,執行正式的事務提交。並在完成事務提交之後釋放所有事務資源。

  • 響應反饋 事務提交完之後,向協調者發送Ack響應。

  • 完成事務 協調者接收到所有參與者的ack響應之後,完成事務。

中斷事務 協調者沒有接收到參與者發送的ACK響應(可能是接受者發送的不是ACK響應,也可能響應超時),那麼就會執行中斷事務。

  • 發送中斷請求 協調者向所有參與者發送abort請求

  • 事務回滾 參與者接收到abort請求之後,利用其在階段二記錄的undo信息來執行事務的回滾操作,並在完成回滾之後釋放所有的事務資源。

  • 反饋結果 參與者完成事務回滾之後,向協調者發送ACK消息

  • 中斷事務 協調者接收到參與者反饋的ACK消息之後,執行事務的中斷。

在doCommit階段,如果參與者無法及時接收到來自協調者的doCommit或者rebort請求時,會在等待超時之後,會繼續進行事務的提交。(其實這個應該是基於概率來決定的,當進入第三階段時,說明參與者在第二階段已經收到了PreCommit請求,那麼協調者產生PreCommit請求的前提條件是他在第二階段開始之前,收到所有參與者的CanCommit響應都是Yes。(一旦參與者收到了PreCommit,意味他知道大家其實都同意修改了)所以,一句話概括就是,當進入第三階段時,由於網絡超時等原因,雖然參與者沒有收到commit或者abort響應,但是他有理由相信:成功提交的幾率很大。 )

2PC與3PC的區別

相對於2PC,3PC主要解決的單點故障問題,並減少阻塞,因為一旦參與者無法及時收到來自協調者的信息之後,他會默認執行commit。而不會一直持有事務資源並處於阻塞狀態。但是這種機制也會導致數據一致性問題,因為,由於網絡原因,協調者發送的abort響應沒有及時被參與者接收到,那麼參與者在等待超時之後執行了commit操作。這樣就和其他接到abort命令並執行回滾的參與者之間存在數據不一致的情況。


分佈式事務解決方案


分享到:


相關文章: