後端程式設計師必備:分布式事務基礎篇

2020-12-15 51CTO

前言

最近看了幾篇有關於分布式事務的博文,做一下筆記。哈哈~

資料庫事務

資料庫事務(簡稱:事務),是資料庫管理系統執行過程中的一個邏輯單位,由一個有限的資料庫操作序列構成,這些操作要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。

資料庫事務的幾個典型特性:原子性(Atomicity )、一致性( Consistency )、隔離性( Isolation)和持久性(Durabilily),簡稱就是ACID。

  • 原子性: 事務作為一個整體被執行,包含在其中的對資料庫的操作要麼全部被執行,要麼都不執行。
  • 一致性: 指在事務開始之前和事務結束以後,數據不會被破壞,假如A帳戶給B帳戶轉10塊錢,不管成功與否,A和B的總金額是不變的。
  • 隔離性: 多個事務並發訪問時,事務之間是相互隔離的,即一個事務不影響其它事務運行效果。簡言之,就是事務之間是進水不犯河水的。
  • 持久性: 表示事務完成以後,該事務對資料庫所作的操作更改,將持久地保存在資料庫之中。

事務的實現原理

本地事務

傳統的單伺服器,單關係型資料庫下的事務,就是本地事務。本地事務由資源管理器管理,JDBC事務就是一個非常典型的本地事務。

事務日誌

innodb事務日誌包括redo log和undo log。

redo log(重做日誌)

redo log通常是物理日誌,記錄的是數據頁的物理修改,而不是某一行或某幾行修改成怎樣,它用來恢復提交後的物理數據頁。

undo log(回滾日誌)

undo log是邏輯日誌,和redo log記錄物理日誌的不一樣。可以這樣認為,當delete一條記錄時,undo log中會記錄一條對應的insert記錄,當update一條記錄時,它記錄一條對應相反的update記錄。

事務ACID特性的實現思想

  • 原子性:是使用 undo log來實現的,如果事務執行過程中出錯或者用戶執行了rollback,系統通過undo log日誌返回事務開始的狀態。
  • 持久性:使用 redo log來實現,只要redo log日誌持久化了,當系統崩潰,即可通過redo log把數據恢復。
  • 隔離性:通過鎖以及MVCC,使事務相互隔離開。
  • 一致性:通過回滾、恢復,以及並發情況下的隔離性,從而實現一致性。

分布式事務

分布式事務: 就是指事務的參與者、支持事務的伺服器、資源伺服器以及事務管理器分別位於不同的分布式系統的不同節點之上。簡單來說,分布式事務指的就是分布式系統中的事務,它的存在就是為了保證不同資料庫節點的數據一致性。

為什麼需要分布式事務?接下來分兩方面闡述:

微服務架構下的分布式事務

隨著網際網路的快速發展,輕盈且功能劃分明確的微服務,登上了歷史舞臺。比如,一個用戶下訂單,購買直播禮物的服務,被拆分成三個service,分別是金幣服務(coinService),下訂單服務(orderService)、禮物服務(giftService)。這些服務都部署在不同的機器上(節點),對應的資料庫(金幣資料庫、訂單資料庫、禮物資料庫)也在不同節點上。

用戶下單購買禮物,禮物資料庫、金幣資料庫、訂單資料庫在不同節點上,用本地事務是不可以的,那麼如何保證不同資料庫(節點)上的數據一致性呢?這就需要分布式事務啦~

分庫分表下的分布式事務

隨著業務的發展,資料庫的數據日益龐大,超過千萬級別的數據,我們就需要對它分庫分表(以前公司是用mycat分庫分表,後來用sharding-jdbc)。一分庫,數據又分布在不同節點上啦,比如有的在深圳機房,有的在北京機房~你再想用本地事務去保證,已經無動於衷啦~還是需要分布式事務啦。

比如A轉10塊給B,A的帳戶數據是在北京機房,B的帳戶數據是在深圳機房。流程如下:

CAP 理論&BASE 理論

學習分布式事務,當然需要了解 CAP 理論和BASE 理論。

CAP理論

CAP理論作為分布式系統的基礎理論,指的是在一個分布式系統中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分區容錯性),這三個要素最多只能同時實現兩點。

一致性(C:Consistency):

一致性是指數據在多個副本之間能否保持一致的特性。例如一個數據在某個分區節點更新之後,在其他分區節點讀出來的數據也是更新之後的數據。

可用性(A:Availability):

可用性是指系統提供的服務必須一直處於可用的狀態,對於用戶的每一個操作請求總是能夠在有限的時間內返回結果。這裡的重點是"有限時間內"和"返回結果"。

分區容錯性(P:Partition tolerance):

分布式系統在遇到任何網絡分區故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務。

選擇 說明 CA 放棄分區容錯性,加強一致性和可用性,其實就是傳統的單機資料庫的選擇 AP 放棄一致性,分區容錯性和可用性,這是很多分布式系統設計時的選擇 CP 放棄可用性,追求一致性和分區容錯性,網絡問題會直接讓整個系統不可用

BASE 理論

BASE 理論, 是對CAP中AP的一個擴展,對於我們的業務系統,我們考慮犧牲一致性來換取系統的可用性和分區容錯性。BASE是Basically Available(基本可用),Soft state(軟狀態),和 Eventually consistent(最終一致性)三個短語的縮寫。

Basically Available

基本可用:通過支持局部故障而不是系統全局故障來實現的。如將用戶分區在 5 個資料庫伺服器上,一個用戶資料庫的故障只影響這臺特定主機那 20% 的用戶,其他用戶不受影響。

Soft State

軟狀態,狀態可以有一段時間不同步

Eventually Consistent

最終一致,最終數據是一致的就可以了,而不是時時保持強一致。

分布式事務的幾種解決方案

分布式事務解決方案主要有以下這幾種:

  • 2PC(二階段提交)方案
  • TCC(Try、Confirm、Cancel)
  • 本地消息表
  • 最大努力通知
  • Saga事務

二階段提交方案

二階段提交方案是常用的分布式事務解決方案。事務的提交分為兩個階段:準備階段和提交執行方案。

二階段提交成功的情況

準備階段,事務管理器向每個資源管理器發送準備消息,如果資源管理器的本地事務操作執行成功,則返回成功。

提交執行階段,如果事務管理器收到了所有資源管理器回復的成功消息,則向每個資源管理器發送提交消息,RM 根據 TM 的指令執行提交。如圖:

二階段提交失敗的情況

準備階段,事務管理器向每個資源管理器發送準備消息,如果資源管理器的本地事務操作執行成功,則返回成功,如果執行失敗,則返回失敗。

提交執行階段,如果事務管理器收到了任何一個資源管理器失敗的消息,則向每個資源管理器發送回滾消息。資源管理器根據事務管理器的指令回滾本地事務操作,釋放所有事務處理過程中使用的鎖資源。

二階段提交優缺點

2PC方案實現起來簡單,成本較低,但是主要有以下缺點

  • 單點問題:如果事務管理器出現故障,資源管理器將一直處於鎖定狀態。
  • 性能問題:所有資源管理器在事務提交階段處於同步阻塞狀態,佔用系統資源,一直到提交完成,才釋放資源,容易導致性能瓶頸。
  • 數據一致性問題:如果有的資源管理器收到提交的消息,有的沒收到,那麼會導致數據不一致問題。

TCC(補償機制)

TCC 採用了補償機制,其核心思想是:針對每個操作,都要註冊一個與其對應的確認和補償(撤銷)操作。

TCC(Try-Confirm-Cancel)模型

TCC(Try-Confirm-Cancel)是通過對業務邏輯的分解來實現分布式事務。針對一個具體的業務服務,TCC 分布式事務模型需要業務系統都實現一下三段邏輯:

try階段: 嘗試去執行,完成所有業務的一致性檢查,預留必須的業務資源。

Confirm階段:該階段對業務進行確認提交,不做任何檢查,因為try階段已經檢查過了,默認Confirm階段是不會出錯的。

Cancel 階段:若業務執行失敗,則進入該階段,它會釋放try階段佔用的所有業務資源,並回滾Confirm階段執行的所有操作。

TCC 分布式事務模型包括三部分:主業務服務、從業務服務、業務活動管理器

  • 主業務服務:主業務服務負責發起並完成整個業務活動。
  • 從業務服務:從業務服務是整個業務活動的參與方,實現Try、Confirm、Cancel操作,供主業務服務調用。
  • 業務活動管理器:業務活動管理器管理控制整個業務活動,包括記錄事務狀態,調用從業務服務的 Confirm 操作,調用從業務服務的 Cancel 操作等。

下面再拿用戶下單購買禮物作為例子來模擬TCC實現分布式事務的過程:

假設用戶A餘額為100金幣,擁有的禮物為5朵。A花了10個金幣,下訂單,購買10朵玫瑰。餘額、訂單、禮物都在不同資料庫。

TCC的Try階段:

  • 生成一條訂單記錄,訂單狀態為待確認。
  • 將用戶A的帳戶金幣中餘額更新為90,凍結金幣為10(預留業務資源)
  • 將用戶的禮物數量為5,預增加數量為10。
  • Try成功之後,便進入Confirm階段
  • Try過程發生任何異常,均進入Cancel階段

TCC的Confirm階段:

  • 訂單狀態更新為已支付
  • 更新用戶餘額為90,可凍結為0
  • 用戶禮物數量更新為15,預增加為0
  • Confirm過程發生任何異常,均進入Cancel階段
  • Confirm過程執行成功,則該事務結束

TCC的Cancel階段:

  • 修改訂單狀態為已取消
  • 更新用戶餘額回100
  • 更新用戶禮物數量為5

TCC優缺點

TCC方案讓應用可以自定義資料庫操作的粒度,降低了鎖衝突,可以提升性能,但是也有以下缺點:

  • 應用侵入性強,try、confirm、cancel三個階段都需要業務邏輯實現。
  • 需要根據網絡、系統故障等不同失敗原因實現不同的回滾策略,實現難度大,一般藉助TCC開源框架,ByteTCC,TCC-transaction,Himly。

本地消息表

ebay最初提出本地消息表這個方案,來解決分布式事務問題。業界目前使用這種方案是比較多的,它的核心思想就是將分布式事務拆分成本地事務進行處理。可以看一下基本的實現流程圖:

基本實現思路

發送消息方:

  • 需要有一個消息表,記錄著消息狀態相關信息。
  • 業務數據和消息表在同一個資料庫,即要保證它倆在同一個本地事務。
  • 在本地事務中處理完業務數據和寫消息表操作後,通過寫消息到MQ消息隊列。
  • 消息會發到消息消費方,如果發送失敗,即進行重試。

消息消費方:

  • 處理消息隊列中的消息,完成自己的業務邏輯。
  • 此時如果本地事務處理成功,則表明已經處理成功了。
  • 如果本地事務處理失敗,那麼就會重試執行。
  • 如果是業務上面的失敗,給消息生產方發送一個業務補償消息,通知進行回滾等操作。

生產方和消費方定時掃描本地消息表,把還沒處理完成的消息或者失敗的消息再發送一遍。如果有靠譜的自動對帳補帳邏輯,這種方案還是非常實用的。

優點&缺點:

該方案的優點是很好地解決了分布式事務問題,實現了最終一致性。缺點是消息表會耦合到業務系統中。

最大努力通知

什麼是最大通知

最大努力通知也是一種分布式事務解決方案。下面是企業網銀轉帳一個例子

  • 企業網銀系統調用前置接口,跳轉到轉帳頁
  • 企業網銀調用轉帳系統接口
  • 轉帳系統完成轉帳處理,向企業網銀系統發起轉帳結果通知,若通知失敗,則轉帳系統按策略進行重複通知。
  • 企業網銀系統未接收到通知,會主動調用轉帳系統的接口查詢轉帳結果。
  • 轉帳系統會遇到退匯等情況,會定時回來對帳。

最大努力通知方案的目標,就是發起通知方通過一定的機制,最大努力將業務處理結果通知到接收方。最大努力通知實現機制如下:

最大努力通知解決方案

要實現最大努力通知,可以採用MQ的ack機制。

方案

  • 1.發起方將通知發給MQ。
  • 2.接收通知方監聽MQ消息。
  • 3.接收通知方收到消息後,處理完業務,回應ack。
  • 4.接收通知方若沒有回應ack,則MQ會間隔1min、5min、10min等重複通知。
  • 5.接受通知方可用消息校對接口,保證消息的一致性。

轉帳業務實現流程圖:

交互流程如下:

  • 1、用戶請求轉帳系統進行轉帳。
  • 2、轉帳系統完成轉帳,將轉帳結果發給MQ。
  • 3、企業網銀系統監聽MQ,接收轉帳結果通知,如果接收不到消息,MQ會重複發送通知。接收到轉帳結果,更新轉帳狀態。
  • 4、企業網銀系統也可以主動查詢轉帳系統的轉帳結果查詢接口,更新轉帳狀態。

Saga事務

Saga事務由普林斯頓大學的Hector Garcia-Molina和Kenneth Salem提出,其核心思想是將長事務拆分為多個本地短事務,由Saga事務協調器協調,如果正常結束那就正常完成,如果某個步驟失敗,則根據相反順序一次調用補償操作。

saga簡介

  • Saga = Long Live Transaction (LLT,長活事務)
  • LLT = T1 + T2 + T3 + ... + Ti(Ti為本地短事務)
  • 每個本地事務Ti 有對應的補償 Ci

Saga的執行順序

  • 正常情況:T1 T2 T3 ... Tn
  • 異常情況:T1 T2 T3 C3 C2 C1

Saga兩種恢復策略

  • 向後恢復,如果任意本地子事務失敗,補償已完成的事務。如異常情況的執行順序T1 T2 Ti Ci C2 C1.
  • 向前恢復,即重試失敗的事務,假設最後每個子事務都會成功。執行順序:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn。

舉個例子,假設用戶下訂單,花10塊錢購買了10多玫瑰,則有

T1=下訂單 ,T2=扣用戶10塊錢,T3=用戶加10朵玫瑰, T4=庫存減10朵玫瑰

C1=取消訂單 ,C2= 給用戶加10塊錢,C3 =用戶減10朵玫瑰, C4=庫存加10朵玫瑰

假設事務執行到T4發生異常回滾,在C4的要把玫瑰給庫存加回去的時候,發現用戶的玫瑰都用掉了,這是Saga的一個缺點,由於事務之間沒有隔離性導致的問題。

【責任編輯:

龐桂玉

TEL:(010)68476606】

點讚 0

相關焦點

  • Spring全家桶、Dubbo、分布式、消息隊列後端必備全套開源項目
    接入 Dubbo 應用」小節Seata《Dubbo 分布式事務 Seata 入門》 對應 lab-53《Spring Cloud Alibaba 分布式事務 Seata 入門》的「2.目前分布式事務的解決方案有 AT、TCC、Saga、MQ、XA、BED 六種。
  • 分布式事務淺析及簡單實現
    作者:翟飛在分布式系統中,為了保證數據的高可用,通常,我們會將數據保留多個副本(replica),這些副本會放置在不同的物理的機器上。為了對用戶提供正確的 CRUD 等語義,我們需要保證這些放置在不同物理機器上的副本是一致的。分布式事務在現在遍地都是分布式部署的系統中幾乎是必要的。
  • 純乾貨|細說分布式事務兩階段提交
    作者:旺德事務的概念在這篇文章中描述過,在分布式系統中,讀寫位於多個節點的數據,如果依舊想保證ACID特性,就必須實現分布式事務。而其實現關鍵則是適當的提交協議,目前最簡潔,且使用最廣泛的無疑是兩階段提交協議(2PC)。
  • 學會設計Saga模型:實現管理跨多個微服務分布式事務
    當服務A執行成功,而服務B執行出現了問題,我們這個分布式事務調用需要調用服務A的補償操作來確保分布式事務的一致性(單個事務失敗,整個分布式事務需要進行回滾),由於這兩個參與服務之間沒有聯繫,因此需要一個協調器來幫助進行相關的恢復。
  • 談談我在項目中是如何解決分布式事務的
    背景我們項目使用的是SpringCloud微服務架構,因為微服務架構所設計的系統是分布式系統,而分布式系統有一個著名的理論叫做CAP理論,即分布式系統同時滿足一致性、可用性、分區容錯是一件不可能的事情。
  • 解決分布式系統事務一致性的幾種方案對比,你有更好的嗎?
    在分布式系統中,同時滿足「一致性」、「可用性」和「分區容錯性」三者是不可能的。分布式系統的事務一致性是一個技術難題,各種解決方案孰優孰劣?寫在前面在 OLTP 系統領域,我們在很多業務場景下都會面臨事務一致性方面的需求,例如最經典的 Bob 給 Smith 轉帳的案例。傳統的企業開發,系統往往是以單體應用形式存在的,也沒有橫跨多個資料庫。
  • 不同職位程式設計師前途一覽
    就程式設計師這個人群而言,其中也存在很多細分。我們總說程式設計師高薪、有前途云云,真正有前途的程式設計師職位是什麼呢?今天我們就來捋一捋。UIUI這個詞近些年很火爆,它涉及到設計,然而又不完全是設計,還涉及到功能實現以及用戶體驗種種方面。設計不同風格的頁面,還要學會與產品經理溝通,與客戶溝通、與程式設計師溝通。遇到麻煩的產品經理或是糾結的客戶,就是對耐心的巨大考驗了。
  • 巨杉資料庫SequoiaDB巨杉TechSequoiaDB 分布式事務實現原理簡介
    1分布式事務背景隨著分布式資料庫技術的發展越來越成熟,業內對於分布式資料庫的要求也由曾經只用滿足解決海量數據的存儲和讀取這類邊緣業務向核心交易業務轉變。分布式資料庫如果要滿足核心帳務類交易需求,則其需要完善分布式事務,向傳統關係型資料庫看齊。即分布式事務的實現也需要像傳統關係型資料庫的事務一樣滿足事務的標準要求及定義,即ACID特徵。分布式資料庫的數據是進行多機器多節點分散存儲的,這樣的存儲架構為實現分布式事務帶來了極大的難度。
  • 乾貨:18 張思維導圖,後端技術學習路線長這樣!
    計算機基礎不管是後端開發還是前端開發,說到底我們所有的軟體開發都是在計算上編寫程序,雖然對於大部分人來說,真正開始寫代碼的時候很少會讓你去解決計算機底層的問題,但不接觸不代表不重要,計算機基礎是最重要的。後端開發工作中經常用到 Java、C++、Python、Golang ,這些語言稱為高級程式語言。
  • 工作三年的Java程式設計師該怎麼擺脫迷茫?
    程式設計師從開始選擇到堅持下去,工作了三年對一個程式設計師意味什麼?在職位上:高級開發工程師?架構師?技術經理?or ... ?在能力上:各種編碼無壓力?核心代碼無壓力?平臺架構無壓力?看著這些問號都心累。相同三年,不同程式設計師卻走在了不同的路線,有些能在三年成為架構師,有些卻還是程式設計師,不是工作年限加長而已,那麼,三年你迷惘了嗎?
  • 阿里P8架構師必備:微服務+Redis+Nginx+MySQL+K8S+Flink+Spark
    前言關乎於程式設計師,除了做項目來提高自身的技術,還有一種提升自己的專業技能就是:多!看!書!畢竟,書是學習的海洋呢!So,Java程式設計師你們準備好了嗎?雙手奉上Java程式設計師必讀之熱門書單:微服務+Redis+Nginx+MySQL+Flink+Spark+K8S還有電子版分享喔,轉發+關注,然後私信我【學習】即可獲得這些書籍電子版的免費領取方式。
  • Seata 實現分布式事務原理,mysql日誌記錄問題,學習下
    數據恢復有兩種策略:- 恢復時,只重做已經提交了的事務- 恢復時,重做所有事務包括未提交的事務和回滾了的事務。03Seata支持的事務模型Seata 會有 4 種分布式事務解決方案,分別是 AT 模式、TCC 模式、Saga 模式和 XA 模式。
  • 淵亭科技圖資料庫DataExa-Seraph:萬億級分布式存儲,毫秒級查詢
    資料庫作為組織、存儲和管理數據的倉庫,是挖掘數據價值的基礎和關鍵。隨著社交、電商、金融等行業的快速發展,現實社會織起了了一張龐大而複雜的關係網,但傳統資料庫很難處理關係運算。圖資料庫的獨特設計恰恰彌補了這個缺陷。
  • 前端難學還是後端難學?發展前景怎麼樣?前端和後端的區別分析
    前端和後端發展前景都挺不錯,都說相對於技術來說前端會比較簡單一點,我不這麼認為。現在前端需要會的東西簡直太多啦。 前端和後端哪個更好? 程式設計師職業解析
  • 優秀程式設計師需要具備的基礎能力
    Java是程式設計師最喜歡的語言,幾乎所有的IT論壇都有不少喜歡Java語言的人,也有不少人想成為Java程式設計師,但很多人不知道應該如何入門,不知道學什麼才能成為合格的Java程式設計師。下面就跟大家討論一下優秀程式設計師應該具備的能力。
  • 床長人工智慧教程免費分享——分布式系統 in 2010s
    黃東旭我覺得面對測試的態度是區分一個普通程式設計師和優秀程式設計師的重要標準。現如今我們的程序和服務越來越龐大,光是單元測試之類的就已經很難保證質量,不過這些都是,所以今天聊點新的話題。說測試之前,我們先問下自己,為什麼要測試?當然是為了找。看起來這是句廢話,但是仔細想想,如果我們能寫出的程序不就好了嗎?何必那麼麻煩。
  • 新品發布會 | T800型大物流後端分揀桁架機器人,叉車物流堆場的...
    發布會現場照片T800型大物流後端分揀桁架機器人是一款快速高效的物流堆場解決方案,專為工廠倉庫中的後端倉儲分揀自動化應用而設計,在同等標準廠房的情況下,相比傳統倉庫物流場地使用率提高300%,與立體倉庫物流等其他自動化解決方案相比場地使用率提高
  • 2020年的Java程式設計師面試三件套:多線程+算法+微服務
    這是一本程式設計師面試寶典!當然,對需要提升算法和數據結構等方面能力的程式設計師而言,本書的價值也是顯而易見的。全書共12章,分為概念篇、開發篇、運維篇和實戰篇。概念篇詳細闡述微服務的由來和設計要點。開發篇介紹Spring Boot、Docker 和Spring Cloud應用於微服務的案例,並且附有原始碼。運維篇從測試、快速開發、質量管理、自動化運維和監控的角度介紹微服務涉及的知識點。實戰篇將企業級開發中涉及的內容儘可能詳細地列出。