最近看了幾篇有關於分布式事務的博文,做一下筆記。哈哈~
資料庫事務(簡稱:事務),是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成,這些操作要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。
資料庫事務的幾個典型特性:原子性(Atomicity )、一致性( Consistency )、隔離性( Isolation)和持久性(Durabilily),簡稱就是ACID。
傳統的單伺服器,單關係型資料庫下的事務,就是本地事務。本地事務由資源管理器管理,JDBC事務就是一個非常典型的本地事務。
innodb事務日誌包括redo log和undo log。
redo log通常是物理日誌,記錄的是數據頁的物理修改,而不是某一行或某幾行修改成怎樣,它用來恢復提交後的物理數據頁。
undo log是邏輯日誌,和redo log記錄物理日誌的不一樣。可以這樣認為,當delete一條記錄時,undo log中會記錄一條對應的insert記錄,當update一條記錄時,它記錄一條對應相反的update記錄。
分布式事務: 就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。簡單來說,分布式事務指的就是分布式系統中的事務,它的存在就是為了保證不同資料庫節點的數據一致性。
為什麼需要分布式事務?接下來分兩方面闡述:
隨著網際網路的快速發展,輕盈且功能劃分明確的微服務,登上了歷史舞臺。比如,一個用戶下訂單,購買直播禮物的服務,被拆分成三個service,分別是金幣服務(coinService),下訂單服務(orderService)、禮物服務(giftService)。這些服務都部署在不同的機器上(節點),對應的資料庫(金幣資料庫、訂單資料庫、禮物資料庫)也在不同節點上。
用戶下單購買禮物,禮物資料庫、金幣資料庫、訂單資料庫在不同節點上,用本地事務是不可以的,那麼如何保證不同資料庫(節點)上的數據一致性呢?這就需要分布式事務啦~
隨著業務的發展,資料庫的數據日益龐大,超過千萬級別的數據,我們就需要對它分庫分表(以前公司是用mycat分庫分表,後來用sharding-jdbc)。一分庫,數據又分布在不同節點上啦,比如有的在深圳機房,有的在北京機房~你再想用本地事務去保證,已經無動於衷啦~還是需要分布式事務啦。
比如A轉10塊給B,A的帳戶數據是在北京機房,B的帳戶數據是在深圳機房。流程如下:
學習分布式事務,當然需要了解 CAP 理論和BASE 理論。
CAP理論作為分布式系統的基礎理論,指的是在一個分布式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),這三個要素最多只能同時實現兩點。
一致性(C:Consistency):
一致性是指數據在多個副本之間能否保持一致的特性。例如一個數據在某個分區節點更新之後,在其他分區節點讀出來的數據也是更新之後的數據。
可用性(A:Availability):
可用性是指系統提供的服務必須一直處於可用的狀態,對於用戶的每一個操作請求總是能夠在有限的時間內返回結果。這裡的重點是"有限時間內"和"返回結果"。
分區容錯性(P:Partition tolerance):
分布式系統在遇到任何網絡分區故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務。
選擇 說明 CA 放棄分區容錯性,加強一致性和可用性,其實就是傳統的單機資料庫的選擇 AP 放棄一致性,分區容錯性和可用性,這是很多分布式系統設計時的選擇 CP 放棄可用性,追求一致性和分區容錯性,網絡問題會直接讓整個系統不可用
BASE 理論, 是對CAP中AP的一個擴展,對於我們的業務系統,我們考慮犧牲一致性來換取系統的可用性和分區容錯性。BASE是Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫。
Basically Available
基本可用:通過支持局部故障而不是系統全局故障來實現的。如將用戶分區在 5 個資料庫伺服器上,一個用戶資料庫的故障只影響這臺特定主機那 20% 的用戶,其他用戶不受影響。
Soft State
軟狀態,狀態可以有一段時間不同步
Eventually Consistent
最終一致,最終數據是一致的就可以了,而不是時時保持強一致。
分布式事務解決方案主要有以下這幾種:
二階段提交方案是常用的分布式事務解決方案。事務的提交分為兩個階段:準備階段和提交執行方案。
準備階段,事務管理器向每個資源管理器發送準備消息,如果資源管理器的本地事務操作執行成功,則返回成功。
提交執行階段,如果事務管理器收到了所有資源管理器回復的成功消息,則向每個資源管理器發送提交消息,RM 根據 TM 的指令執行提交。如圖:
準備階段,事務管理器向每個資源管理器發送準備消息,如果資源管理器的本地事務操作執行成功,則返回成功,如果執行失敗,則返回失敗。
提交執行階段,如果事務管理器收到了任何一個資源管理器失敗的消息,則向每個資源管理器發送回滾消息。資源管理器根據事務管理器的指令回滾本地事務操作,釋放所有事務處理過程中使用的鎖資源。
2PC方案實現起來簡單,成本較低,但是主要有以下缺點:
TCC 採用了補償機制,其核心思想是:針對每個操作,都要註冊一個與其對應的確認和補償(撤銷)操作。
TCC(Try-Confirm-Cancel)是通過對業務邏輯的分解來實現分布式事務。針對一個具體的業務服務,TCC 分布式事務模型需要業務系統都實現一下三段邏輯:
try階段: 嘗試去執行,完成所有業務的一致性檢查,預留必須的業務資源。
Confirm階段:該階段對業務進行確認提交,不做任何檢查,因為try階段已經檢查過了,默認Confirm階段是不會出錯的。
Cancel 階段:若業務執行失敗,則進入該階段,它會釋放try階段佔用的所有業務資源,並回滾Confirm階段執行的所有操作。
TCC 分布式事務模型包括三部分:主業務服務、從業務服務、業務活動管理器。
下面再拿用戶下單購買禮物作為例子來模擬TCC實現分布式事務的過程:
假設用戶A餘額為100金幣,擁有的禮物為5朵。A花了10個金幣,下訂單,購買10朵玫瑰。餘額、訂單、禮物都在不同資料庫。
TCC的Try階段:
TCC的Confirm階段:
TCC的Cancel階段:
TCC方案讓應用可以自定義資料庫操作的粒度,降低了鎖衝突,可以提升性能,但是也有以下缺點:
ebay最初提出本地消息表這個方案,來解決分布式事務問題。業界目前使用這種方案是比較多的,它的核心思想就是將分布式事務拆分成本地事務進行處理。可以看一下基本的實現流程圖:
發送消息方:
消息消費方:
生產方和消費方定時掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發送一遍。如果有靠譜的自動對帳補帳邏輯,這種方案還是非常實用的。
該方案的優點是很好地解決了分布式事務問題,實現了最終一致性。缺點是消息表會耦合到業務系統中。
最大努力通知也是一種分布式事務解決方案。下面是企業網銀轉帳一個例子
最大努力通知方案的目標,就是發起通知方通過一定的機制,最大努力將業務處理結果通知到接收方。最大努力通知實現機制如下:
要實現最大努力通知,可以採用MQ的ack機制。
方案
轉帳業務實現流程圖:
交互流程如下:
Saga事務由普林斯頓大學的Hector Garcia-Molina和Kenneth Salem提出,其核心思想是將長事務拆分為多個本地短事務,由Saga事務協調器協調,如果正常結束那就正常完成,如果某個步驟失敗,則根據相反順序一次調用補償操作。
saga簡介
Saga的執行順序
Saga兩種恢復策略
舉個例子,假設用戶下訂單,花10塊錢購買了10多玫瑰,則有
T1=下訂單 ,T2=扣用戶10塊錢,T3=用戶加10朵玫瑰, T4=庫存減10朵玫瑰
C1=取消訂單 ,C2= 給用戶加10塊錢,C3 =用戶減10朵玫瑰, C4=庫存加10朵玫瑰
假設事務執行到T4發生異常回滾,在C4的要把玫瑰給庫存加回去的時候,發現用戶的玫瑰都用掉了,這是Saga的一個缺點,由於事務之間沒有隔離性導致的問題。
【責任編輯:
龐桂玉TEL:(010)68476606】