天天看點

seata阿裡分布式事務架構了解

更新下最新文檔:http://seata.io/zh-cn/docs/overview/what_is_seata.html

seata全局鎖的了解

前幾天夜裡,我老大發我一篇文章說阿裡的GTS開源了.
因為一直對分布式事務比較感興趣。立馬pull了代碼,進行閱讀。
基本的原理,實作方案我就不一一細化了,詳細見官方文檔(寫的很棒,點贊)。 

在fescar的社群,大家比較關注的是通過fescar復原到before快照前,别的線程假如更新了資料,且業務走完了,那麼恢複的這個快照不就是髒資料了麼。
很顯然,這種情況在fescar中是不被允許的。

那麼fescar是如何做的呢?
           

我們先簡單了解一下fescar的設計原理

那些一上來就喜歡看源碼的同學,一定不要錯過這麼官方的圖文介紹,看完再讀源碼事半功倍.
           

Fescar官方介紹

了解完seata的基本原理,我們重點關注下Fescar的全局排他鎖

Fescar設計了一個**全局的排他鎖**,來保證事務間的 **寫隔離**。
           

關于隔離性:(這是seata官方給的一段話)

全局事務的隔離性是建立在分支事務的本地隔離級别基礎之上的。

在資料庫本地隔離級别  **讀已送出或以上** 的前提下,Fescar 設計了由事務協調器維護的 全局寫排他鎖,來保證事務間的 寫隔離,将 **全局事務預設定義在 讀未送出 的隔離級别上**。

我們對隔離級别的共識是:絕大部分應用在讀已送出的隔離級别下工作是沒有問題的。而實際上,這當中又有絕大多數的應用場景,實際上工作在讀未送出的隔離級别下同樣沒有問題。

在極端場景下,應用如果需要達到全局的讀已送出,Fescar也提供了相應的機制來達到目的。
預設,Fescar 是工作在 讀無送出 的隔離級别下,保證絕大多數場景的高效性。
           

我的解讀

本地事務【讀已送出】,fescar全局事務【讀未送出】。這是這段話的核心。
我了解的這段話中fescar全局事務讀未送出,并不是說本地事務的db資料沒有正常送出,而是指全局事務二階段commit|rollback未真正處理完(即未釋放全局鎖)。

總結來說:全局未送出但是本地已送出的資料,對其他全局事務是可見的【當然在本地事務送出後,本地事務送出前,隔離級别是本地事務的管轄範圍】

for example
産品份額有5W,A使用者購買了2萬,份額branch一階段完畢(本地事務份額已經扣除commit),但是在下單的時候異常了。
因為本地事務讀已送出,這時候fescar允許業務通路該條資料,3W,在A使用者的份額branch未復原成功前,對其他使用者可見。
但是其他使用者并不能買該産品,必須等到産品份額復原到5萬,其他使用者才可以操作産品資料。

是以看了這個例子 真的有必要做到全局事務讀已送出麼?
           

我們先來看一下Fescar的全局鎖的做法

seata一階段

1. 本地(Branch)在向TC注冊的時候,把本地事務需要修改的資料table+pks送出到server端申請鎖,拿到全局鎖後,才能送出本地事務
2. 全局鎖的結構:resourceId + table + pks
3. 鎖是存在server端 branchSession中
           

seata二階段

一階段本地事務送出,db的鎖釋放了(for update鎖),但是全局鎖繼續保持,
直到二階段決議(注意釋放鎖的順序):
1. 送出:TC 釋放鎖,通知branch送出後 (rm端異步處理)
2. 復原:TC 通知branch復原後,釋放鎖(rm端同步處理 執行undo_log)
           

seata如何保障鎖的高效?

大家自己先思考下,最後給大家仔細解讀官方的demo,并分析fescar的性能問題
           

seata目前開源版本全局鎖的實作

大家有興趣自己閱讀:com.alibaba.fescar.server.lock.DefaultLockManagerImpl
           

官方的圖實在是做的太漂亮了,clone一份解讀 TC TM RM 以及全局鎖的擷取和釋放動作發生點

分支事務如何工作?關注全局鎖的擷取和釋放 特别是二階段commit和rollback全局鎖釋放的順序
           
seata阿裡分布式事務架構了解

ATBranch.png

Fescar中 RM TM TC如何工作的?
           
seata阿裡分布式事務架構了解

AT distribute transaction.png

看了這兩張圖,大家應該對fescar是如何工作的應該有一個大緻的了解了。☺
1、全局鎖的擷取
2、tm tc rm之間如何通信工作
3、隔離級别問題的思考
           

最後我們來解讀一遍官方的demo

  • branch1:update storage_tbl set count = count - ? where commodity_code = ?
  • branch2:update account_tbl set money = money - ? where user_id = ?
  • branch3:insert into order_tbl (user_id, commodity_code, count, money) values (?, ?, ?, ?)
  1. 線程A:執行branch1(pk:55),執行branch2的時候發現沒錢了,扔了一個異常,那麼勢必需要復原branch1的份額。
    • TM通知TC開始復原branch1份額中
  2. 線程B:執行branch1(pk:55)
    • 如果線程A中branch1(pk:55)已經復原成功了,那麼B線程可以正常拿到鎖走下去
    • 如果線程A中branch1還未復原(resourceId+table+pk鎖未釋放)。當線程B發起branch1向server發起申請鎖,會直接失敗。

Fescar全局鎖簡單總結:操作一條記錄的分支事務,必須等待這條記錄的前一個分支事務執行結束(具體commit rollback情況分析如下),才能持有鎖。

其實相比XA的鎖,fescar在每個分支事務的一階段結束後都釋放了db的鎖,是以fescar的性能瓶頸應該在于二階段的執行速度(釋放鎖的快慢)

因為分布式事務在執行事務編排前,一般會校驗業務的正确性,是以發生復原的機率相對較低,是以先考慮二階段commit操作。

  1. Commit場景分析:
    TM通知server進行commit,server立馬釋 branch的鎖,然後再逐個通知RM送出
     消耗:1 rpc操作,(branch删除undo_log放在異步隊列裡面做)
               
  2. Rollback場景分析:
    TM通知server進行rollback,server通知RM復原後立馬釋放 branch的鎖。
     消耗:1 + N的rpc操作 + N的復原sql操作
               

是以總的來看fescar在commit的釋放全局鎖還是非常高效的。

思考

1. server支援多台機器部署,應該如何改造?

    全局鎖的問題,鎖改造;
    全局事務向server0申請的,Branch1發到server1,branch2發到server2的問題,多機器恢複的情況,TC的改造

2. 全局鎖在Fescar中更新确實是沒有問題的,但是如果就是業務方需要手動調整DB資料呢?

    大膽猜測,依賴Fescar寫了一個管理平台 用來執行sql的。哈哈

3. 隔離級别的思考
    Fescar預設工作在,本地事務讀已送出,全局事務讀未送出。
    是否存在全局事務必須工作在【讀已送出】級别而不能工作在【讀未送出】的業務場景呢?
    大家大膽腦洞 這個問題值得探讨。

4. Fescar的文檔中說,是支援全局事務讀已送出的,那麼fescar是如何實作的呢?

   感興趣的同學可以試着讀一下com.alibaba.fescar.rm.datasource.exec.SelectForUpdateExecutor
           

源碼核心類

大家想讀源碼的話,可以重點關注一下幾個類。有問題一起探讨。

TM相關
com.alibaba.fescar.tm.api.TransactionalTemplate

RM相關
com.alibaba.fescar.rm.datasource.exec.SelectForUpdateExecutor
com.alibaba.fescar.rm.datasource.ConnectionProxy
com.alibaba.fescar.rm.datasource.exec.AbstractDMLBaseExecutor
com.alibaba.fescar.rm.RMHandlerAT

TC相關
com.alibaba.fescar.server.coordinator.DefaultCoordinator
com.alibaba.fescar.server.coordinator.DefaultCore
com.alibaba.fescar.server.lock.DefaultLockManagerImpl
           
  • Github:https://github.com/alibaba/fescar
  • Fescar官方介紹:https://github.com/alibaba/fescar/wiki/Home_Chinese

作者:陽雨人

連結:https://www.jianshu.com/p/4cb127b737cf

來源:簡書

簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。

繼續閱讀