「若干分佈式事務框架」與「個人偏見」( 測試/分析)

本文來談談我對若干分佈式事務框架的見解,只談設計時致使沒法輕易改變的硬傷(或者說個人偏見),其優勢應該已表如今其文檔中,再也不贅述。至於個人偏見能不能成爲你的偏見,請自行思考覈實,僅供你們選型時開拓思路使用。git

靶子

如下我略有了解的框架將成爲靶子:github

  • TransactionsEssentials(atomikos免費版)
  • tcc-transaction
  • ByteTCC
  • hmily
  • tx-lcn
  • GTS
  • EasyTransaction

TransactionsEssentials

其是atomikos公司的兩階段提交事務的免費版本,說到兩階段提交你們第一印象應該都是慢,第二印象應該就是很方便,編碼少。數據庫

但實際上有多慢呢?可能你們都不太肯定,我這裏有一組數字供你們參考,相同業務場景,兩個服務有數據協同需求:編程

  • 若兩個服務在同一庫中,單庫事務可達600TPS+
  • 但Atomikos速度爲40-70TPS

固然,這裏沒有給出具體的場景與配置,確實差值也有點大,我當時也是不太相信的。但我從多個不一樣測試數據源得到的數據都較爲相似,你們有空能夠協助驗證下,而後評論給下數據。安全

因此對於TransactionsEssentials這個框架,個人偏見就是,太慢。網絡

tcc-transaction

這是一個在GITHUB上開源了好久的框架了,其STAR數量接近3K,其代碼簡潔易懂。但其有三個缺點:併發

  • 應用Crash時有概率致使持久化的事務狀態不正確
  • 不支持框架冪

慢的緣由

  • 事務日誌使用一個數據庫的變長字段存儲
  • 會屢次更新該字段
  • 該字段存儲的內容不斷變長,使其不能在磁盤中原地更新,致使頁的分裂,或者致使該字段從頁中移除,涉及大量IO

CRASH不一致的緣由

  • 其CRASH後純粹依賴事務日誌判斷全局事務狀態(Trying,Confirming,Canceling)
  • 然而該事務日誌記錄的事務狀態是沒法與業務數據庫的事務狀態保持強一致的(若能,則須要引入2PC等手段,是否是很矛盾)
  • 所以在Crash時致使事務日誌狀態不正確時,按照目前的設計是須要人工介入排查問題的

不支持框架冪等

這會致使業務開發工做量大大增長。mvc

ByteTCC

ByteTCC是一個兼容JTA規範的基於TCC機制的分佈式事務管理器。框架

其實我的以爲基JTA規範擴展的TCC實現並不是一個特別好的想法,其異步

  • 強制Spring的PlatformTransactionManager要支持JTA,須要用戶修改原有的PlatformTransactionManager
  • 使用了ByteTCC自行實現的UserTransaction(JTA相關接口),並在裏層整合"TCC"及「真JTA」的控制邏輯,這違反了編程裏的開閉原則
    • 用自定義實現類替換掉了客戶原有實現中可能更爲可靠的JTA/JDBC事務,即單機事務的代碼邏輯也被改了
    • 在JTA接口中整合「真JTA」及「TCC」的邏輯交錯在整個實現中,沒有很好地分離邏輯,不利於閱讀,也不利於修改
    • 限制了使用其餘的JTA實現

不知道你們有沒有聽懂我上面說了什麼,其實就是說,若是讓我來設計,我是儘可能不會對原有邏輯進行修改,而是對邏輯進行擴展,這樣才能最大程度的程序的安全性,也能更好地與原有邏輯整合。

舉個例子,EasyTransaction裏就是基於擴展實現了各類功能,其能保證原有事務處理邏輯徹底不變,僅僅只是外掛了TCC、可靠消息等等的實現,同等狀況下,其實現的理論風險會更小,而且EasyTransaction能無縫兼容JTA事務以及EasyTransaction內的各類事務,並協調一塊兒工做,而ByteTCC則因爲其實現形式,難以簡單作到。

另一個方面是其代碼變得過於複雜,至少對我來講有理解難度,須要一些額外的知識支撐,不知道其餘人的見解是怎樣的。

同時關於冪等,ByteTCC只支持Confirm及Cancel操做的冪等,不過這比不少框架都要強了。

hmily

這個框架的主要描述是「高性能分佈式事務tcc方案開源框架」,我的感受其之因此這麼聲稱是由於「採用disruptor框架進行事務日誌的異步讀寫,與RPC框架的性能毫無差異」。

這裏有兩個我的認爲的硬傷(也許是偏見吧):

  • 異步寫入事務日誌就等於TCC是不可靠的
  • 持久化IO瓶頸纔是一個分佈式事務框架的主要瓶頸,其並不是Disruptor框架主要針對的CPU瓶頸

爲何不可靠

就一個簡單的問題吧,事務日誌存儲鏈接不上(網絡斷掉/掉電了),這時異步寫入的日誌放到內存了,而後遠程的訪問請求TRY發出去了,這個時候應用CRASH了。這就會致使TCC日誌不完整,從而致使事務沒法恢復。

有一些觀點認爲這些狀況極其少見,不需處理,那咱們併發編程時volatile之類的同步手段還須要用麼?

而且異常都是連鎖的,它並非孤立出現的,咱們沒法預判會出現什麼異常狀況,也有墨菲定律說,越擔憂的事情越有可能發生,所以咱們對於這類狀況必然是雖然咱們不能保證明現完美,可是咱們的理論至少要使完美的。

異步的Disruptor並不能解決矛盾的主要方面

咱們知道,CPU的速度會比持久化IO的速度高不少個數量級,所以,基本上涉及持久化時,IO必然纔是主要優化的目標。

所以咱們作優化時,仿照KAFKA等,批量聚集數據,批量IO纔是正確的解決之道。不作這個而去優化CPU性能這有點本末倒置,同時據我瞭解的多個測試結果中,hmily的性能都大幅不及EasyTransaction。

也不支持框架冪等

同上Tcc-transaction

tx-lcn

這個框架本質上是一個BestEffors 1PC的框架,是什麼意思呢,也就是大多數狀況下,只要應用不Crash就不會致使不一致。

這裏帶來什麼矛盾呢?除非你不關心不一致,容許數據出錯不修復,但一旦出現數據不一致必定要修復的狀況的話,就要走人工補償處理,或者調用相關的修復程序。

而人工補償處理,實際上,也就至關於人肉寫了一遍修復程序,並且人肉執行還沒留下代碼,下次出問題還要人工再分析處理一遍。

所以,結論很明顯:

  • 對於容許數據不一致的數據來講
    • 用BestEffors 1PC挺好的,性能高於2PC,代碼量與2PC同樣。
  • 可是對於數據出現不一致時,必須修復的狀況
    • 咱們必需要寫對應的修復程序
    • 這實際上跟TCC/補償等工做量同樣了
    • 爲啥不切換到TCC/補償等性能更加高的形式
    • 而且使用BestEffors1PC寫的業務代碼在出現數據異常時,並不能保證其後續的補償是可執行的。
    • 舉個例子,轉帳,出現了給別人加錢了,可是本身沒有扣錢的數據異常,此時兩位客戶就有可能立馬把錢取出來用掉

tx-lcn這個框架是有適用場景的,可是我我的以爲最好把相關的厲害關係放到險要位置,否則有巨多小白無腦就用了,而不知道其中的坑,我以爲不太好。

GTS

這個框架的偏見嘛,主要就是髒讀了。貼一段以前寫過的文字。

GTS確實很贊,其核心原理是補償。

但這個補償作得很屌,補償操做由框架自動生成,無需業務干預,框架會記錄修改前的記錄值到上面的txc_undo_log裏,若須要回滾,則拿出undo_log的記錄覆蓋回原有記錄

同時這裏存在一個事務隔離級別的問題,GTS的作法是默認髒讀,那麼就能夠直接拿數據庫記錄展現(但我的以爲應該能夠不作髒讀,直接拿undo_log裏的記錄作mvcc,只要undo_log記錄不大,均可以加載到內存裏)。

還有另一個問題是如何禁止其餘事務對進行中的全局事務記錄的更新,GTS的作法是須要接管APP中的數據源,這樣就能夠解析控制業務要執行的SQL,對於update操做(或者select for update),予以禁止或等待。

不過總體的作法至關於魔改數據庫,將數據庫的部分功能拉到了業務APP裏進行,並修改了默認隔離級別(髒讀,若是業務有用數據庫記錄樂觀鎖來控制併發的話,將會失效),還有就是,不經過GTS的定製數據源訪問會訪問修改到未提交數據

EasyTransaction

這個嘛,是我本身寫的框架,上面出現的偏見,在我這裏都不會有,這篇文章本質是個軟文,哈哈,因此ET在我這沒有偏見,但我彙總下ET的優勢把:

  • 真正的高性能,對IO作了大量優化,多個獨立三方公司橫向評測分佈式事務框架時,同等場景及同等可靠性保證下性能最佳(可自行驗證測試)
  • 理論上只要外部組件不丟數據,在ET內部是不會出現事務不完整的狀況(相對於上面一些框架,其原理就不可靠,運行出現異常能夠說是必然的)
  • 支持框架冪等,業務程序程序再也不須要接管 冪等、調用時序錯亂處理等繁瑣重複邏輯(這個是一個繁瑣重複的工做,貌似只有ET對本項進行了完整支持)
  • 基於擴展的實現,而非基於修改的實現,更易理解,風險更小,功能更強大
  • 支持多種事務形態(TCC,補償,可靠消息,SAGAs等)混合使用,可按照最適合業務的選擇最貼切的事務形態(這時ET建立之初的理念及特色,也是其餘框架所不具備的特性)

總結

以上的偏見是不成熟的小想法,如有不正確,各位大佬儘管在評論區拍磚。同時本文僅供各位大佬選型時開拓思路,我認爲的偏見不必定就是你的偏見,可能僅僅只是考慮角度、設計理念不同而已。

我的認爲EasyTransaction的理念、設計、可靠性、性能等都不會比上面的框架差,但ET的STAR數量卻不及上面的各個開源框架,我以爲必定是ET有什麼我本身沒有察覺到的缺陷,請你們拍磚以促進本框架進步,能夠直接評論,或者到GITHUB上提ISSUE,感謝你的改進建議!

https://github.com/QNJR-GROUP/EasyTransaction
相關文章
相關標籤/搜索