天天看點

幾種分布式事務實作方案

目錄

CAP(Consistency、Availability、Partition Tolerence)理論

BASE理論

2PC兩階段送出方案/XA方案

TCC方案

可靠消息最終一緻性方案

最大努力通知方案

CAP(Consistency、Availability、Partition Tolerence)理論

一、一緻性(C)

就是說一個分布式系統中,一旦你做了一個資料的修改,那麼這個操作成功的時候,就必須是分布式系統的各個節點都是一樣的。

例如用戶端發起一個資料修改的請求,然後伺服器傳回成功了,結果去查的時候,從某個節點上查詢資料,發現這個資料不對,這樣的話就成了資料不一緻了,就是分布式系統的各個節點上的資料是不一樣的,也就是所謂的強一緻性。

弱一緻性,就是更新資料後,不确定各個節點間是否都更新成功;最終一緻性,就是更新後,一段時間内不一緻,但是最後過了一段時間各個節點間都更新成功。

二、可用性(A)

就是說分布式系統必須是可用的

三、分區容錯性(P)

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

四、CP

經典的就是一些分布式存儲,比如說zookeeper、mongodb、hbase等等,跟他們都是CP的,也就是說資料100%一緻,但是有可能有些時候你請求是失敗的,不讓你請求到不一緻的資料,這就是CP。

五、AP

如果網絡故障,資料沒同步,資料處于不一緻的狀态下,要保證A,可用性,你兩個節點都要允許任何用戶端來查詢,都可以查到,這樣的話呢,整個系統就處于可用的狀态下,但是此時就犧牲掉了C。

對于12306、電商系統,這種業務類系統,一般都是AP,也就是說,你可能看到的商品庫存或者火車票的庫存,是錯的,有可能是舊的啊,那麼資料很可能看到的都是不一緻的,但是呢,你買東西或者買票的時候,一定會檢查庫存,就可以了,但是保證了可用性,任何時候都要響應結果。

BASE理論

所謂的BASE,Basicly Available、Soft State、Eventual Consistency,也就是基本可用、軟狀态、最終一緻性。

BASE希望的是,CAP裡面基本都可以同時實作,但是不要求同時全部100%完美的實作,CAP三者同時基本實作,BASE,基本可用、最終一緻性

此時要保證基本可用性,兩個節點都可以查詢的,但是這個時候會發現有的節點可以傳回資料,有的節點無法傳回資料,會看到不一緻的狀态,這個不一緻的狀态,就是指的是BASE中的S,soft state,軟狀态;

基本可用,降級,正常情況下,是查詢可以負載均衡到各個節點去查的,也就是可以多節點抗高并發查詢,但是此時如果你要降級的話,可以降級為,所有用戶端強制查詢主節點,這樣看到的資料暫時而言都是一樣的,都是從主節點去查。因為用戶端通路量太大了,同時用一個主節點來支撐很坑,扛不住,怎麼辦呢,主節點做限流降級,也就是說如果流量太大了,直接傳回一個空,讓你稍後再來查詢;

最終一緻性,一旦故障或者延遲解決了,資料過了一段時間最終一定是可以同步到其他節點的,資料最終一定是可以處于一緻性的。

2PC兩階段送出方案/XA方案

将事務的送出過程分成送出事務請求和執行事務送出兩個階段進行處理。這種分布式事務方案,比較适合單塊應用裡,跨多個庫的分布式事務,而且因為嚴重依賴于資料庫層面來搞定複雜的事務,效率很低,不适合高并發的場景。

TCC方案

try接口裡是鎖定資源,confirm是業務邏輯,cancel是復原邏輯

try接口裡,一般就是預留資源,比如說經典的資金轉賬,卡掉一些鎖定資金,要是不這麼控制,萬一别的分布式事務給幹掉了一些資金,那麼實際執行confirm的時候一旦檢查資金餘額就會發現轉賬失敗,餘額不足了;有些接口,沒有資源鎖定的操作,try接口就留白。

confirm就是原來的業務方法,執行實際的轉賬操作,A銀行賬戶的資金扣減,B銀行賬戶的資金增加。

cnacel接口,要提供復原的方法,就是把try或者confirm裡的操作給復原。

比如說,如果是try階段,資金服務的try成功了,資金被當機了,結果訂單服務的try失敗了,主業務服務就會通知復原,調用資金服務的cancel接口,将當機的金額給解凍。

confirm階段,資金服務,把錢從iA賬号裡轉移到B賬号裡去了,結果某一服務的confirm失敗了,整個分布式事務復原,調用各個接口的cancel接口。

(1)、空復原

當沒有調用參與方Try方法的情況下,就調用了二階段的Cancel方法,Cancel方法需要有辦法識别出此時Try有沒有執行。如果Try還沒執行,表示這個Cancel操作是無效的,即本次Cancel屬于空復原;如果Try已經執行,那麼執行的是正常的復原邏輯。

(2)、倒置請求

比如調用try接口,中間網絡逾時,結果認定失敗,直接調用cancel空復原;結果過了幾秒鐘try接口請求到來,要在這個時候不允許執行try接口操作;同理,confirm請求逾時了,結果都cancel掉了,但是過了幾秒請求來了,也不允許執行confirm操作。

(3)、接口的幂等性保證

try、confirm和cancel都可能被多次調用,是以得保證這幾個接口的幂等性,分布式接口幂等性那必須依賴第三方的中間件來實作,可以考慮使用經典的zk,zk非常适用于分布式系統的協調類操作。是以一個接口對同一個參數調用,隻能調用一次,保證幂等操作。

可靠消息最終一緻性方案

這個方案,适合于那那種比較耗時的操作,通過這個消息中間件做成異步調用,發送一個消息出去,由服務消費消息來執行業務邏輯。

1)A系統先發送一個prepared消息到mq,如果這個prepared消息發送失敗那麼就直接取消操作;

2)如果這個消息發送成功過了,那麼接着執行本地事務,如果成功就告訴mq發送确認消息,如果失敗就告訴mq復原消息;

3)如果發送了确認消息,那麼此時B系統會接收到确認消息,然後執行本地的事務;

4)mq會自動定時輪詢所有prepared消息回調接口,這個消息是不是本地事務處理失敗了,所有沒發送确認消息?那是繼續重試還是復原?一般來說這裡你就可以查下資料庫看之前本地事務是否執行,如果復原了,那麼這裡也復原吧。這個就是避免可能本地事務執行成功了,别确認消息發送失敗了。

5)這個方案裡,要是系統B的事務失敗了咋辦?自動不斷重試直到成功,如果實在是不行,要麼就是針對重要的資金類業務進行復原,比如B系統本地復原後,想辦法通知系統A也復原;或者是發送報警由人工來手工復原和補償

調用第三方營運商系統接口的操作,适合用可靠消息最終一緻性的方案。

最大努力通知方案

跟可靠消息最終一緻性方案是類似的,可靠消息最終一緻性方案,會保證最終必須要讓那個執行成功的,但是最大努力通知方案,不一定保證最終一定會成功,可能會失敗,但是他會盡力給你去給你通知那個服務的執行。

比較适合那種不太核心一些服務調用的操作,比如說消息服務,充值好了以後發送短信,一般來說肯定是要發出去短信的,但是如果真的不小心發送失敗了,發送短信失敗了也無所謂的。

繼續閱讀