本文將會對比Seata與EasyTransaction兩個分布式事務的一些高層設計,相信大家會有收獲。
Seata的概述
Seata(曾用名Fescar,開源版本GTS)是阿里的開源分布式事務框架,其RoadMap中指出了其希望與社區合作重新構建出一個全面的分布式事務框架。
關於Seata的相關介紹可以看這里,本文不再贅述。雖然其后續路線有所調整,但整體適用。
https://github.com/seata/seata/wiki/%E6%A6%82%E8%A7%88
學習了解Seata后我們可以比對着了解EasyTransaction的架構設計。
EasyTransaction概述
EasyTransaction(后簡稱ET)的目標也是構建出一個全面分布式事務解決方案,到目前為止其包含TCC,自動補償(Seata AT),手動補償,可靠事務消息、Saga事務等等多種形態。
下面將就兩個框架在設計上的差異進行分析
核心差異圖示
借用Seata的一張圖:
與Seata不同,EasyTransaction對應的圖如下:
TC差異
Seata:
- 有獨立部署的集中式TC
- RM、TM與TC的交互通過RPC進行
- TC中可以看到每個具體的事務分支,統一協調所有事務分支的提交及回滾
EasyTransaction:
- TC是業務服務進程中的一個模塊,並沒有獨立出來,且存在子事務的服務實例都會調用起TC模塊
- 如ServiceA,B,C都有TC,但ServiceD,E沒有
- 這里的有無指代的是這一次事務里TC的功能有沒有被觸發
- TC與TM,RM的交互在進程內進行
- 每個TC只能協調其直接子事務
- 如ServiceA的TC只知道ServiceB及ServiceE的子事務
- 但ServiceB知道還有ServiceC的子事務,因此可以遞歸協調
- 每個服務實例發起的全局事務,服務實例自身會先嘗試一次自協調(大多數都能成功),若自協調失敗,則由一個服務實例兜底處理事務協調
Seata有集中式的TC,這樣其可以 更容易 實現對分布式事務的監管控,如關於APM、Metrics、統一限流 等等功能。
但在EasyTransaction中的TC形式可以節約TC網絡交互時間,在上述Seata的業務圖中,ET的形式在兩階段提交中的第一階段能節約6次 網絡來回時間 及 正反序列化時間。
[(registerBranch以及reportBranch)* n個調用層級]
在兩階段提交的第二階段中,統一提交或者回滾過程中,Seata的形式則是比EasyTransaction快,因為其不需要層級傳遞下去。視調用層級N的區別,ET形態的第二階段會比Seata慢 n-1 個網絡來回及正反序列化的的時間。
[ (commit或者rollback) * (n-1)個調用層級]
(注:若考慮commit/rollback的次序的話,實際上 seata要按照 業務發生順序依次提交 或者 逆序回滾,其也為串行,這也為其默認做法,所以實際上ET在這個階段也會比Seata快一個 網絡來回及正反序列化的的時間)
至於 由於數據分散性等等原因APM、Metrics、統一限流 等等功能在ET形式如何實現 的這個問題,我們可以參考普通的RPC是怎么做的,將其納入統一的RPC管理即可,只是統一管控的力度沒有集中式的強大。
同時分散型的TC能 更容易 達到更高級別的可用性,其無需保證TC是否存活,業務服務在則TC在。分散的特征也讓壓力能在正常業務情況下,能均勻分散到不同的業務實例當中。
TM差異
Seata:
- 獨立於Spring/JTA的TransactionManager單獨創建了另外一套TransactionManager
- TransactionManager在一個全局事務里只有一個
EasyTransaction:
- 擴展Spring的PlatformTransactionManager(后稱PTM)的功能,使其可以管控分布式事務
- 在每個事務分支里都有PTM(Spring原生的事務),但存在子事務的PTM將會掛載擴展分布式事務相關處理以及啟動TC模塊功能
Seata單獨抽象了一套TM,其好處是自由可控,並可以不依賴於任何框架。
ET其TM依賴於Spring的PTM的話,Spring這個框架就變成了使用ET的必選項。但相對的好處就是,所有作用於這個PTM的設施都可以作用於EasyTransaction。
例如Spring的RollbackFor,Transactional,Suspend注解,XML事務切面配置等等都可以直接為EasyTransaction所用。因為ET僅僅只是擴展,因此這些功能都能兼容。甚至於我們要引入JTA,EasyTransaction也能兼容,因為PTM自身就有JTA的實現。
RM差異
Seata:
- 所有參與到全局事務的RM都是平等的存在
EasyTransaction
- 存在主控RM(發起方RM、發起方事務),從事務RM的區別
Seata全局事務里的RM都是平等的存在,整體邏輯上有簡單統一的美,但因此其所有的RM都必須能接受兩階段的管控。
但在常規的業務模式中,全局事務開始者(Seata里帶TM的那個)的事務,基本都可以在一階段內獲知全局事務應該回滾或者提交,但由於Seata RM都平等的模式,發起方RM必要要用AT模式(記錄回滾數據),或者編寫TCC的提交回滾方法,這里有一些額外的性能損耗
ET模式里存在事務發起方RM的設定,其只要事務發起方的事務提交成功則全局事務(最終)提交,發起方事務提交失敗則全局事務(最終)回滾,因此其事務發起方無需兼容兩階段提交的協議,節約了相關的性能成本。當然,ET的事務發起方RM也可以不寫入任何業務,這樣的話,就跟Seata的模式一樣了。
自動補償實現差異
Seata:
- 全局鎖通過TC保存並實現
EasyTransaction:
- 全局鎖通過本地業務數據庫保存
Seata通過TC保存全局記錄鎖引入了更多的復雜度,但其能自由控制鎖的實現,能針對場景實現出效率更高的鎖。
EasyTransction改造Seata的自動補償功能,將原有的遠程TC依賴改造成了EasyTransaction的分布式TC,並將全局鎖實現改造到業務DB中。自動補償的整體實現復雜度降低了,但性能可能有所下降(未經測試)。
不過Seata相關的實現也在進行中
RPC接口
Seata
- 初期Seata試圖維持其核心功能簡潔,不涉及任何業務層次RPC的內容
- 后面整合螞蟻的TCC后框架核心代碼開始出現RPC相關內容
- 暴露給用戶的是RPC框架原生的接口
- 接口入參出參形式較為自由
EasyTransaction
- RPC是EasyTransaction的一部分,其可更改替換
- 直接暴露給用戶使用的並非RPC框架,而是ET的相關接口,RPC僅作為底層通訊的支持
- 接口入參出參形式有限制
EasyTransaction沒有采用常規的做法,而是用自己的接口替代原RPC接口的一個原因是這樣做能對整個事務過程能 更容易 地把控,其直接與業務交互,知道這一次調用的結果需要馬上返回還是可以稍后返回,知道這一次調用是重試還是業務主動觸發的,可以通過sdk主動設置RPC框架不進行重試,主動設置使其進行黏性會話以提高效率而不用用戶額外單獨配置
同時因為RPC是ET的一部分,因此冪等、cancel懸掛等等繁瑣重復的問題,能更容易地通過框架自動支持(已經實現),但如果Seata堅持目前輕量級做法的話,將來在實現相關功能時可能會更困難。
當然對業務暴露了ET的接口也算是一種耦合的增強。
動態配置、服務發現、APM等
Seata
- 通過主動配置對接
EasyTransaction
- 利用Spring等現有設施對接
ET利用Spring現有的配置接口進行配置,因此只要相關配置中心對接了Spring,EasyTransaction就能使用。但Seata為了減少對Spring的依賴,因此相關對接需要單獨進行。
ET的TC整合到業務服務中,因此TC相關的服務發現只要利用業務自身的服務發現就能完成。而Seata的TC單獨部署,因此需要一定的適配工作。
跟上面的原因類似,EasyTransaction的APM等操作只需借用已經整合到RPC框架的APM即可,而Seata需要一定的適配工作
總結
Seata在短短幾個月內能積累近萬Star除了阿里的技術號召力外,當然還有另外一個原因是分布式事務領域如此普遍且重要,但缺少一個能讓小白都能放心無腦使用權威的實現,無疑Seata在如此熱烈的社區支持下很有希望能成為這么一個實現。
但在Seata真正成為這個權威實現前,我覺得大家也可以抽空了解下EasyTransaction這個目前功能更為強大、代碼更為穩定、已上過生產的實現~
當然以上內容很多都帶個人主觀偏見,希望各位能補充各種看法,兼聽則明!
作者個人公眾號
多年金融行業經驗,現為某Top2互聯網(民營)銀行高級搬磚工,曾在兩家TOP3股份制商業銀行及一家互金創業公司工作(架構、核心業務主程),EasyTransaction作者,歡迎關注個人公眾號,在這里我會分享日常工作、生活中對於架構、編碼和業務的思考。
公眾號
作者微信,添加微信請附上 暗號 ET