.net core分布式事務落地(1)-分布式概念及解決方案


目錄

  1. 為什么需要分布式

    1.1 傳統架構帶來的局限性

    1.2 系統復雜帶來的維護性

  2. 分布式帶來的問題-CAP分布式事務

    2.1 Consistency(數據一致性)

    2.2  Availability(系統可用性)

    2.3  Partition tolerance(分區容錯性)

  3. 分布式事務的解決方案

    3.1 強一致性

      3.1.1 介紹

      3.1.2 方案

        3.1.2.1 2PC

          3.1.2.1.1 簡介

          3.1.2.1.2 2PC示例

          3.1.2.1.3 優點

          3.1.2.1.4 缺點

        3.1.2.2 3PC

          3.1.2.2.1 簡介

          3.1.2.2.2 3PC示例

          3.1.2.2.3 優點

          3.1.2.2.4 缺點

    3.2 弱一致性

      3.2.1 介紹

      3.2.2 方案

        3.2.2.1 TCC

          3.2.2.1.1 簡介

          3.2.2.1.2 TCC示例

          3.2.2.1.3 優點

          3.2.2.1.4 缺點

        3.2.2.2 Saga

          3.2.2.2.1 簡介

          3.2.2.2.2 Sage示例

          3.2.2.2.3 優點

          3.2.2.2.4 缺點

    3.3 最終一致性

      3.3.1 介紹

      3.3.2 方案:本地消息表+隊列

      3.3.3 優點

      3.3.4 缺點

 

1.  為什么需要分布式?

  為什么系統需要分布式,我認為可以從兩個個方面出發:

  1.1傳統架構帶來的局限性

    傳統系統架構是將整個系統做成一個服務來對外提供服務,所有的業務步驟都在一個服務內完成,將這個服務部署到一台計算機上。但是我們都知道單台計算機的性能是有限的,從而導致一台計算機能處理的請求是局限的,最終的結果是處理不了業務從而直接導致經濟損失。

    舉個實際生活中的例子,比如:開發一個軟件,我們將它的步驟分為:收集需求-需求分析-系統設計-系統開發-測試-上線-運維等。規定在三個月內做完,如果這些事都交給一個人來干,三個月肯定是干不完的。所以需要將步驟拆分出去,增加人手,每個步驟由專門的人去干,整個開發以迭代式的方  式進行。其實將整個步驟拆分開,分別執行,這個就好比我們將整個系統進行拆分,拆分成一個個子系統,每個子系統運行在不同的計算機上。組合起來共同完成任務。這就是分布式,也是為什么需要分布式的原因之一。

  1.2系統復雜帶來的維護性

    傳統系統架構因為將整個業務都寫在一個服務內,所有的代碼都堆疊在一起,隨着業務的復雜性越來越大,導致系統越來越難維護。而分布式,將業務拆分開來,每個子系統負責自己的業務,獨立維護。從而大大的提高了系統的可維護性。

 

2.  分布式帶來的問題-CAP

  因整個業務系統拆分成一個一個子系統,分別運行在不同的計算機上,從而帶來了三個問題

  2.1 Consistency(數據一致性)

    因每個業務系統分部在不同計算機,中間可能因為各種原因導致數據不一致。例如:電商系統中將訂單和支付分為兩個子系統,現有這么一個操作,用戶支付了某個訂單,該操作會調用支付系統和訂單系統進行支付和更新訂單狀態,那么如果在支付成功之后更新訂單失敗,那么就導致數據不一致。

  2.2 Availability(系統可用性)

    系統可用性,因為有多個子系統,一旦某個子系統不可用,將會導致整個系統不可用。例如:電商系統中的訂單和支付子系統,當支付子系統宕機或者說請求堵塞了,將會導致后續請求及業務無法處理,從而帶來經濟損失,導致整個系統無法使用。

  2.3 Partition tolerance(分區容錯性)

    一個分布式系統里面,節點組成的網絡本來應該是連通的。然而可能因為一些故障,使得有些節點之間不連通了,整個網絡就分成了幾塊區域。數據就散布在了這些不連通的區域中。這就叫分區。

    當你一個數據項只在一個節點中保存,那么分區出現后,和這個節點不連通的部分就訪問不到這個數據了。這是分區就是無法容忍的。

    提高分區容忍性的辦法就是一個數據項復制到多個節點上,那么出現分區之后,這一數據項就可能分布到各個區里。容忍性就提高了。

    然而,要把數據復制到多個節點,就會帶來一致性的問題,就是多個節點上面的數據可能是不一致的。要保證一致,每次寫操作就都要等待全部節點寫成功,而這等待又會帶來可用性的問題。

    總的來說就是,數據存在的節點越多,分區容忍性越高,但要復制更新的數據就越多,一致性就越難保證。為了保證一致性,更新所有節點數據所需要的時間就越長,可用性就會降低。

3.  CAP的解決方案

  CAP三個問題中,P(分區容錯)是固定存在的,主要是在於C(數據一致性)和P(系統可用性)之間做出取舍。針對二者,主要有三個方案。

  3.1強一致性

    3.1.1介紹

      強一致性的本質是對資源進行鎖定,然后在進行相關操作,從而保證在任何時刻所有的用戶或者進程查詢到的都是最近一次成功更新的數據。最具代表性的方案有:2PC、3PC。

    3.1.2方案

      3.1.2.1 2PC
        3.1.2.1.1 簡介

        2PC是解決分布式事務的一個協議,當一個事務跨越多個節點時,為了保持事務的ACID特性,需要引入一個coordinator,即協調者作為的組件來統一掌控所有節點(稱作參與者)的操作結果並最終指示這些節點是否要把操作結果進行真正的提交或回滾。

        2PC 本質是: 參與者將操作成敗通知協調者,再由協調者根據所有參與者的反饋決定各參與者是否要提交操作還是回滾操作。

 

        3.1.2.1.2 2PC示例:

        還是拿上面的操作來說,電商系統中,有兩個子系統:訂單和支付。現有一用戶支付某一訂單,支付成功之后需修改訂單狀態。

        在2PC中,需要經過兩個步驟,第一,准備提交,鎖定資源。第二,提交事務,確認提交。整個流程是,由協調者向支付系統跟訂單系統發送准備提交的請求,當兩個子系統都返回准備完成時,這個時候資源是被鎖住的,也就是咱們的數據或者表被鎖定了。其次,當兩個都返回成功之后,協調者在將事務真正提交,然后進行一個事務提交完成確認的過程,如果都返回成功,那么整個事務就成功了。

        以下為事務成功示意圖:

 

 

 

 

圖:2PC成功事務示意圖

        如果說在事務中間有一步出現錯誤或者說提交失敗,例如,當支付成功,更新訂單提交事務的時候,確認提交失敗,那么協調者將會通知所有事務回滾。以下為示例圖:

 

 

 

圖:提交事務失敗示意圖

        當更新訂單操作,確認提交事務失敗,那么協調者將會給支付系統及訂單系統發送回滾事務操作。最終返回支付失敗。

      3.1.2.1.3 優點

                       1. 數據一致性很高,用戶或者進程查詢到的都是最近一次成功更新的數據

      3.1.2.1.4 缺點

        1. 當某個協調者本身在提交完事務之后宕機,那么其他參與者將會處於一個停滯狀態,會一直鎖住數據庫資源,從而導致系統卡住。

        2. 因為2PC是處理事務是連鎖的,進行一個支付訂單操作,將鎖住兩個子系統,從而導致被鎖住的時間,這兩個系統是無法使用的,整個系統能承載的用戶量就比較小,也就是吞吐量降低。

    3.1.2.2 3PC
      3.1.2.2.1 簡介

      因2PC存在巨大缺陷,協調者宕機,將導致整個系統被鎖住,於是便有了3PC的出現,3PC其本質是基於2PC,在2PC的基礎上引入了兩個,分別是:

    1. 超時機制。在協調者和參與者中都引入超時機制。一旦協調者或者參與者未能得到恢復,超過一定時間將認為事務失敗,則進行回滾。
    2. 新增事務預備階段。在准備步驟和提交事務步驟中插入了一個PreCommit步驟,用於確認並保證提交事務前各參與節點狀態一致。
      3.1.2.2.2 3PC示例

      那么上面的例子,用戶支付某個訂單,就變成了這樣:

 

 

 

      預提交事務,並不會真正執行事務,只是用於確認參與者能否執行事務,確認參與者的狀態等。

      超時機制,當3個環節,只要有一個環節超時,比如協調者宕機,那么其余參與者將自動回滾事務。在例如訂單系統宕機,那么協調者將發送事務回滾。

 

      3.1.2.2.3 優點

      1. 數據一致性很高,用戶或者進程查詢到的都是最近一次成功更新的數據

      3.1.2.2.4 缺點

                     1. 事務會鎖定數據庫資源,系統可用性較低,能承載的請求數有限。

  3.2弱一致性

    3.2.1介紹

      因為強一致性的方案會導致數據被鎖住,整個系統吞吐量降低。於是就有了弱一致性,而弱一致性的本質是在程序級別執行事務,主要是保存了數據的變化版本,一旦出現執行出現錯誤,那么將執行回滾,將數據回滾到初始狀態。弱一致性最具代表性的方案有:TCC、Saga。

    3.2.2方案

      3.2.2.1 TCC
        3.2.2.1.1 簡介

        TCC全稱(Try Confirm Cancel),是分布式事務弱一致性的一種解決方案,本質上是在業務服務層實現事務,對於每個業務的子系統都需要需要實現三個方法,分別是:Try嘗試執行業務、 Confirm確認執行業務、 Cancel 取消執行業務。

      1. Try的作用及目標:
        • 完成所有業務檢查(一致性)
        • 預留必須業務資源(准隔離性)     

          2. Confirm的作用及目標:

        • 真正執行業務
        • 不作任何業務檢查
        • 只使用Try階段預留的業務資源
        • Confirm操作要滿足冪等性

          3. Cancel的作用及目標:

        • 釋放Try階段預留的業務資源 
        • Cancel操作要滿足冪等性
         3.2.2.1.2 TCC示例

              還是以電商系統中的訂單及支付子系統為例,對於同樣的操作,用戶支付某個訂單,在TCC中是如何實現:

 

 

 

圖:TCC用戶支付某訂單示意圖

             第一步,先分別調用訂單系統及支付系統的try接口,如果返回成功,那么則進行第二步操作。

             第二步,分別調用支付及訂單系統的confirm接口,如果成功,則整個業務成功。

             如果中間某一個環節出現錯誤,例如調用支付的try成功了,調用訂單的try失敗。那么將調用其它系統的cancel接口進行回滾,以下為示意圖:

 

 

 

圖:TCC某節點調用失敗

        3.2.2.1.3 優點:
      1. 相對於2PC、3PC來說,因為事務在業務服務層,事務不會鎖定數據庫資源,能提高系統可用性。
      2. 沒有單獨的准備(Prepare)階段, Try操作兼備資源操作與准備能力 。
      3. 因為是在業務服務層執行事務,可以靈活選擇業務資源的鎖定粒度。
        3.2.2.1.4 缺點:

                       1. 提升了開發成本,每個業務需要實現三個接口。

      3.2.2.2 Saga
        3.2.2.1 簡介

        Saga是一種分布式事物的補償協議,業務流程中每個參與者都提交本地事務,當出現某一個參與者失敗則補償前面已經成功的參與者。其正向服務(具體業務)及補償服務(回滾,撤銷)都由業務開發實現。與TCC相似。

        3.2.2.2 Saga示例

        我們繼續上面的業務場景,還是訂單系統和支付系統,依舊是相同的操作,用戶支付某訂單。在Saga中,需要實現一個補償事務的方法,主要用於事務失敗之后執行,整個業務流程為:第一,分別向訂單系統及支付系統發送請求,支付成功之后更新訂單,二者系統本地分別啟動事務。第二,如果執行成功,那么整個業務操作成功,如果失敗,那么將執行補償事務的方法,進行事務回滾。以下為示意圖:

 

 

 

圖:Saga成功示意圖

 

 

 

圖:Saga失敗示意圖

        3.2.2.3 優點
      1. 相對於2PC、3PC來說,因為事務在業務服務層,事務不會鎖定數據庫資源,能提高系統可用性。
      2. 沒有單獨的准備(Prepare)階段,性能提升。
      3. 因為是在業務服務層執行事務,可以靈活選擇業務資源的鎖定粒度。
        3.2.2.4 缺點

                         1. 提升了開發成本,每個業務需要實現兩個接口。

  3.3最終一致性

      3.3.1 簡介

        因強一致性和弱一致性,或多或少都會鎖定資源,對於高並發場景,並不太適合。於是便有了數據最終一致性,數據最終一致性的本質是,數據暫時可以不一致,但是最終數據是一致的。例如:銀行轉賬,可以先扣除一方的錢,但是另一方可以暫時沒收到,但是最終還是需要收到,轉賬成功的。其具體實現是,如果失敗,則不斷地重試,如果重試一定次數,那么進行人工操作,完成業務。最終一致性的方案用的最多的還是使用本地消息表,基於EventBus模式去實現。

      3.3.2 方案:本地消息表+隊列

        我們還是以電商系統中的訂單和支付系統為例子,依舊是用戶支付某訂單,那么在最終一致性下,是這樣的:第一,業務端發起一個支付。第二支付系統,支付某個訂單,將支付完成的消息放入本地消息表中,一個線程讀取本地信息放入隊列中,第三訂單系統,讀取隊列信息,獲取支付成功的某個訂單信息,存放本地消息表,然后啟動本地事務進行訂單的更新。如果中間有失敗,那么先會有一個重試機制,如果重試失敗,最終進行人工處理。以下為示意圖

 

圖:最終一致性示意圖

 

        如果中間有環節失敗,比如訂單同步消息失敗,那么也是走人工處理。一般來說,走人工處理的可能性幾乎不存在,最終一致性的目的是,本身用戶就要干這個事情,那么這個事情一定是要成功的。

      3.3.3 優點

                  1. 不會鎖住資源,極大的提高了系統可用性

                  2. 利用第三方隊列或者其它手段,進行系統之間解耦。

                  3. 沒有任何准備階段,只需要提交數據就行

      3.3.4 缺點

                  1. 數據短時間內不一致

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM