Yige

Yige

Build

分布式事務

分佈式事務#

內容來自

  1. 極客時間專欄:《分佈式技術原理與算法解析》
  2. 再有人問你分佈式事務,把這篇扔給他
  3. 對分佈式事務及兩階段提交、三階段提交的理解

事務,其實是包含一系列操作的、一個有邊界的工作序列,有明確的開始和結束標誌,且要麼被完全執行,要麼完全失敗回滾。而分佈式事務,就是在分佈式系統中運行的事務,由多個本地事務組合而成。

事務的基本特徵ACID#

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔離性(Isolation)
  • 持久性(Durability)

CAP 和 BASE 理論#

CAP#

  • Consistency (一致性): 對某個指定的客戶端來說,讀操作能返回最新的寫操作。對於數據分佈在不同節點上的數據來說,如果在某個節點更新了數據,那麼在其他節點如果都能讀取到這個最新的數據,那麼就稱為強一致,如果有某個節點沒有讀取到,那就是分佈式不一致。
  • Availability (可用性):非故障的節點在合理的時間內返回合理的響應 (不是錯誤和超時的響應)。可用性的兩個關鍵一個是合理的時間,一個是合理的響應。合理的時間指的是請求不能無限被阻塞,應該在合理的時間給出返回。合理的響應指的是系統應該明確返回結果並且結果是正確的,這裡的正確指的是比如應該返回 50,而不是返回 40。
  • Partition tolerance (分區容錯性): 當出現網絡分區後,系統能夠繼續工作。打個比方,這裡的集群有多台機器,有台機器網絡出現了問題,但是這個集群仍然可以正常工作。

CAP 理論告訴我們:一個分佈式系統不可能同時滿足一致性 (C)、可用性 (A)、分區容錯性 (P tolerance) 這三個基本需求,並且最多只能滿足其中的兩項,參考鏈接:

BASE#

BASE 理論包括基本可用(Basically Available)軟狀態(Soft State)最終一致性(Eventual Consistency)

  • 基本可用:分佈式系統出現故障的時候,允許損失一部分功能的可用性。比如,某些電商 618 大促的時候,會對一些非核心鏈路的功能進行降級處理。
  • 軟狀態:在柔性事務中,允許系統存在中間狀態,且這個中間狀態不會影響系統整體可用性。比如,數據庫讀寫分離,寫庫同步到讀庫(主庫同步到從庫)會有一個延時,其實就是一種柔性狀態。
  • 最終一致性:事務在操作過程中可能會由於同步延遲等問題導致不一致,但最終狀態下,數據都是一致的。

BASE 解決了 CAP 中理論沒有網絡延遲,在 BASE 中用軟狀態和最終一致,保證了延遲後的一致性。BASE 和 ACID 是相反的,它完全不同於 ACID 的強一致性模型,而是通過犧牲強一致性來獲得可用性,並允許數據在一段時間內是不一致的,但最終達到一致狀態。

實現分佈式事務的方法#

  1. 基於 XA 協議的二階段提交協議方法;
  2. 三階段提交協議方法;
  3. TCC 事務機制;
  4. 本地消息表;
  5. Saga 事務。

其中,基於 XA 協議的二階段提交協議方法和三階段提交協議方法,採用了強一致性,遵從 ACID,基於消息的最終一致性方法,採用了最終一致性,遵從 BASE 理論。

1、基於 XA 協議的二階段提交方法 (2PC)#

XA 實現分佈式事務的原理,類似於分佈式互斥中的集中式算法,由事務管理器作為協調者,負責各個本地資源的提交和回滾。

流程#

image.png

第一階段:事務管理器要求每個涉及到事務的數據庫預提交 (precommit) 此操作,並反映是否可以提交。

第二階段:事務協調器要求每個數據庫提交數據,或者回滾數據。

缺點分析#

  • 同步阻塞問題:二階段提交算法在執行過程中,所有參與節點都是事務阻塞型的。也就是說,當本地資源管理器佔有臨界資源時,其他資源管理器如果要訪問同一臨界資源,會處於阻塞狀態。
  • 單點故障問題:基於 XA 的二階段提交算法類似於集中式算法,一旦事務管理器發生故障,整個系統都處於停滯狀態。尤其是在提交階段,一旦事務管理器發生故障,資源管理器會由於等待管理器的消息,而一直鎖定事務資源,導致整個系統被阻塞。
  • 數據不一致問題:在提交階段,當協調者向參與者發送 DoCommit 請求之後,如果發生了局部網絡異常,或者在發送提交請求的過程中協調者發生了故障,就會導致只有一部分參與者接收到了提交請求並執行提交操作,但其他未接到提交請求的那部分參與者則無法執行事務提交。於是整個分佈式系統便出現了數據不一致的問題。

2、三階段提交協議方法 (3PC)#

三階段提交協議(Three-phase commit protocol,3PC),是對二階段提交(2PC)的改進,三階段提交引入了超時機制和準備階段

  • 超時機制:如果協調者或參與者在規定的時間內沒有接收到來自其他節點的響應,就會根據當前的狀態選擇提交或者終止整個事務。
  • 準備階段:也就是在提交階段之前,加入了一個預提交階段。在預提交階段排除一些不一致的情況,保證在最後提交之前各參與節點的狀態是一致的。

流程#

3PC 把 2PC 的提交階段一分為二,這樣三階段提交協議就有 CanCommit、PreCommit、DoCommit 三個階段。
image.png

  • CanCommit:
    CanCommit 階段與 2PC 的投票階段類似:協調者向參與者發送請求操作(CanCommit 請求),詢問參與者是否可以執行事務提交操作,然後等待參與者的響應;參與者收到 CanCommit 請求之後,回覆 Yes,表示可以順利執行事務;否則回覆 No。

  • PreCommit: 協調者根據參與者的回覆情況,來決定是否可以進行 PreCommit 操作。

    1. 如果所有參與者回覆的都是 “Yes”,那麼協調者就會執行事務的預執行。
    2. 假如任何一個參與者向協調者發送了 “No” 消息,或者等待超時之後,協調者都沒有收到參與者的響應,就執行中斷事務的操作。
  • DoCommit: DoCommit 階段進行真正的事務提交,根據 PreCommit 階段協調者發送的消息,進入執行提交階段或事務中斷階段。

和 2PC 的對比#

  • 相較於 2PC 而言,3PC 對於協調者和參與者都設置了超時時間,而 2PC 只有協調者才擁有超時機制。避免了參與者在長時間無法與協調者節點通訊(協調者掛掉了)的情況下,無法釋放資源的問題,因為參與者自身擁有超時機制會在超時後,自動進行本地 commit 從而進行釋放資源。而這種機制也側面降低了整個事務的阻塞時間和範圍。
  • 在 2PC 的準備階段和提交階段之間,多設置了一個預提交階段 (PreCommit),相當於加了一個緩衝階段保證了在最後提交階段之前各參與節點的狀態是一致的。

3、TCC 事務機制#

TCC(Try-Confirm-Cancel)又稱補償事務。其核心思想是:"針對每個操作都要註冊一個與其對應的確認和補償(撤銷操作)"。它分為三個操作:

  • Try 階段:主要是對業務系統做檢測及資源預留。
  • Confirm 階段:確認執行業務操作。
  • Cancel 階段:取消執行業務操作。

image.png

適用場景

  • 強隔離性,嚴格一致性要求的活動業務。
  • 執行時間較短的業務。

4、本地消息表#

在 eBay 的分佈式系統架構中,解決一致性問題的核心思想就是:將需要分佈式處理的事務通過消息或者日誌的方式異步執行,消息或日誌可以存到本地文件、數據庫或消息隊列中,再通過業務規則進行失敗重試。
參考:Base: An Acid Alternative

5、Saga 事務#

Saga 是 30 年前一篇數據庫倫理提到的概念。其核心思想是將長事務拆分為多個本地短事務,由 Saga 事務協調器協調,如果正常結束那就正常完成,如果某個步驟失敗,則根據相反順序一次調用補償操作。

要注意的是,在 saga 模式中不能保證隔離性,因為沒有鎖住資源,其他事務依然可以覆蓋或者影響當前事務,可以參照華為的解決方案:從業務層面入手加入一 Session 以及鎖的機制來保證能夠串行化操作資源。也可以在業務層面通過預先凍結資金的方式隔離這部分資源,最後在業務操作的過程中可以通過及時讀取當前狀態的方式獲取到最新的更新。

具體實例:可以參考華為的 servicecomb。

拓展#

剛性事務與柔性事務#

  • 剛性事務,遵循 ACID 原則,具有強一致性。比如,數據庫事務。
  • 柔性事務,其實就是根據不同的業務場景使用不同的方法實現最終一致性,也就是說我們可以根據業務的特性做部分取舍,容忍一定時間內的數據不一致。

總結來講,與剛性事務不同,柔性事務允許一定時間內,不同節點的數據不一致,但要求最終一致。而柔性事務的最終一致性,遵循的是 BASE 理論。

分佈式互斥與分佈式事務之間的關係#

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。