Spring Cloud的分散式事務框架壓測第一輪
原文地址:http://springcloud.cn/view/374
前言
分散式事務對微服務開發者而言是既想努力避免又無法完全迴避的蛋疼問題。通過使用分散式事務處理框架可以很大程度上解決分散式事務所帶來的事務效能、可靠性問題,以及引入的編碼複雜性。本文由海信HICS技術團隊壓測提供,目前國內主要的開源分散式事務框架框架包括:
框架名稱 | GitHub地址 | star數量 |
---|---|---|
社群開源專案dts | https://github.com/venusteam/dts | 111 |
tcc-transaction | https://github.com/changmingxie/tcc-transaction | 2192 |
Hmily | https://github.com/yu199195/hmily | 1196 |
ByteTCC | https://github.com/liuyangming/ByteTCC | 1137 |
myth | https://github.com/yu199195/myth | 894 |
EasyTransaction | https://github.com/QNJR-GROUP/EasyTransaction |
805 |
tx-lcn | https://github.com/codingapi/tx-lcn/ | 802 |
我們響應springcloud社群的號召,計劃對上框架的非功能對比測試,希望對大家日後的選型有所幫助。
本文是此測試的第一輪,本輪對不使用訊息中介軟體的分散式事務處理模式進行了測試(包括TCC、廣義上的2PC,3PC等),測試框架包括:
- EasyTransaction(僅TCC模式)
- ByteTCC
- tcc-transaction
- Hmily
- LCN
測試硬體環境
應用伺服器規格均為(2核4G,例項規格ecs.c5.large)
mysql資料庫規格為(RDS配置為2核4G,例項規格rds.mysql.s2.large,MySQL5.7高可用版)
ECS主機與RDS均在同一內網環境下
測試業務場景
本測試場景涉及三個服務:
- 訂單服務
- 支付服務
- 庫存服務
使用者請求訂單服務建立訂單,訂單服務作為事務發起者,發起分散式事務,訂單服務分別請求庫存服務與支付服務完成相應操作,從而完成一個分散式事務。
- 新增訂單資訊
- 新增訂單明細資訊
- 新增/更新商品統計資訊
- 查詢商品資訊
- 查詢商品品類資訊
- 查詢更新商品統計資訊
- 新增支付資訊
- 新增支付優惠資訊
- 新增/更新支付統計資訊
- 查詢支付統計資訊
- 新增庫存變動資訊
- 更新庫存資訊
- 查詢庫存資訊
測試說明
- 針對上面的框架進行效能測試,對於效能較好的框架會進一步進行事務可靠性測試
- 商品庫模擬了1000種商品
- 測試軟體使用 Apache JMeter,模擬在30到200個執行緒情況下,測試各個框架的平均響應時間與平均TPS數值。一般而言,平均響應時間越低,平均TPS數值越高,則效能越好。
效能測試
分散式事務測試結果概要
先上效能測試結果,有時間的同學可以看詳細的測試過程
名次 | 框架名稱 | 最高平均TPS |
---|---|---|
對照組 | 本地事務 | 850.2 |
1 | LCN | 554.6 |
2 | EasyTransaction | 346.4 |
3 | Hmily | 132.3 |
4 | tcc-transaction | 127.7 |
測試參考基準
先將所有的分散式事務邏輯以及資料庫操作在一個單體服務的本地事務中完成做為本次後續效能測試的對照基準。
我們測試了在30、50、100、150、200個執行緒下,本地事務情況下的TPS測試結果如下:
執行緒數 | 平均TPS | 平均響應時間(ms) |
---|---|---|
30執行緒 | 850.2 | 35 |
50執行緒 | 847.1 | 58 |
100執行緒 | 845.2 | 117 |
150執行緒 | 828.2 | 178 |
200執行緒 | 828.4 | 236 |
基準測試效能瓶頸在資料庫上,資料庫的CPU佔用達90%以上。
tcc-transaction
首先,測試star最多的tcc-transaction,本次測試使用1.2.x分支。
tcc-transaction在GitHub上有完整的使用說明文件,並且提供了基於dubbo、http等方式的demo,對於使用者來說比較友好。
tcc-transaction在使用上通過註解的形式編寫分散式事務的confirm與cancel程式碼,具有程式碼入侵性較小的特點。
對於tcc-transaction,測試其在30、50、100個執行緒下的表現,測試結果如下:
執行緒數 | 平均TPS | 平均響應時間(ms) |
---|---|---|
30執行緒 | 125.6 | 236 |
50執行緒 | 127.7 | 387 |
100執行緒 | 125.5 | 785 |
分析發現tcc-transaction的效能壓力主要集中在資料庫上,一個分散式事務涉及至少四次框架層面的資料庫操作,一次插入、至少兩次更新、一次刪除,由下圖可以看出操作耗時大約在15ms,對比其他框架的1~2ms可以說是響應時間非常慢了。其中操作耗時長的表中均有多個長欄位,包括一個長度是8000、型別為VARBINARY的欄位,且更新與插入的比例高於其他框架的事務操作比例。
此外資料庫出入網路流量在120TPS時,已達到28M/s,頻寬佔用高達224Mbps。即使資料庫伺服器效能提高,在千兆網路環境下,頻寬佔用將成為瓶頸。
Hmily
然後,測試star數第二的Hmily。
Hmily有作者自己部落格上的原始碼解析文章,還有錄製的環境搭建和原始碼詳解的視訊,框架支援dubbo、motan、springcloud多種RPC框架,作者也給出了以上RPC框架的demo程式碼,對於開發者來說,瞭解原始碼與使用框架都非常方便。
說明
- 測試demo基於框架自帶的Spring Cloud demo改造,執行依賴Eureka
對於Hmily,測試其在50、100、200執行緒下的表現,測試結果如下:
執行緒數 | 平均TPS | 平均響應時間(ms) |
---|---|---|
50執行緒 | 132.3 | 377 |
100執行緒 | 123.5 | 806 |
200執行緒 | 130.4 | 1530 |
通過工具分析發現,Hmily在壓力測試中,執行緒大部分時間處於阻塞狀態,多數執行緒都處於等待鎖的狀態中。
通過追蹤處於阻塞狀態執行緒的呼叫方法棧,注意到StarterHmilyTransactionHandler類中有一個可重入鎖,這個鎖加在了confirm階段,這個加鎖對於效能產生了影響,導致多數的執行緒處於阻塞的狀態。confirm加鎖能夠防止發生錯亂,但是對效能卻產生較大的影響,建議作者優化confirm加鎖的方式,提高框架的效能。
ByteTCC
接下來是僅比Hmily少59個star而屈居第三位的BtyeTCC。
ByteTCC在有使用方法的文件,也提供了dubbo、springcloud兩種RPC框架的demo,開發者入門比較方便。
然而在上週測試ByteTCC時,框架提供的springcloud demo卻不能正常執行,由於測試時間比較緊張的關係,沒有時間基於ByteTCC框架自行開發測試demo,因此ByteTCC的測試暫時擱置,希望ByteTCC作者更新一下示例demo,使得demo更加易用。
EasyTransaction
EasyTransaction基於TCC、補償以及訊息佇列等多種形式實現了分散式事務,不同的實現形式可以在同一個分散式事務中使用,開發者可以選擇自己適用的場景開發。但是,EasyTransaction示例程式碼只有單元測試程式碼,demo程式碼不及以上幾個框架,對於開發者不夠易用。EasyTransaction對於程式碼的入侵性比較大,不及其他框架方便。
說明
- 測試demo基於單元測試程式碼使用Spring Cloud自行開發,執行依賴Eureka
- 執行EasyTransaction框架依賴ZooKeeper、Kafka
- 僅測試EasyTransaction框架的TCC場景
對於EasyTransaction,測試其在30、50、100、150執行緒下的表現,測試結果如下:
執行緒數 | 平均TPS | 平均響應時間(ms) |
---|---|---|
30執行緒 | 334.5 | 89 |
50執行緒 | 346.4 | 143 |
100執行緒 | 346.4 | 286 |
150執行緒 | 345.1 | 426 |
EasyTransaction在簡單的效能測試中未發現明顯的效能問題,其遠端呼叫採用了多執行緒的處理方式,較大的提升了框架的效能。但在測試中發現框架存在兩個問題:
- 即使只使用TCC,在框架啟動時也會檢查是否部署了訊息中介軟體。
- 雖然有遠端呼叫超時處理的註解,但未實現。
LCN
最後是star數最少的LCN。
LCN有比較全面的文件,包括原理介紹、使用說明、視訊講解,演示demo等,而且LCN對於業務程式碼的入侵性極小,開發者使用起來也比較方便。不過LCN需要單獨部署txmanager服務。
說明
- 測試demo基於框架自帶的Spring Cloud demo改造,執行依賴Eureka
- 執行LCN框架依賴tx-manager
對於LCN,測試其在50、100、150執行緒下的表現,測試結果如下:
執行緒數 | 平均TPS | 平均響應時間(ms) |
---|---|---|
50執行緒 | 455.3 | 109 |
100執行緒 | 530.2 | 188 |
150執行緒 | 554.6 | 269 |
在簡單的效能測試中未發現明顯的效能問題。在A效能場景中表現最好。
為進一步評估LCN和EasyTransaction的效能,我們又對訂單集中在單一商品的場景進行了測試,以瞭解框架在訪問集中在某個業務實體的情況下的效能表現。
對於EasyTransaction與LCN,我們增加了單個商品的測試,就是說所有請求都會更新一條商品的庫存資料。
採用50個執行緒,最終測試結果如下:
單個商品TPS | 一千個商品TPS | 下降比率 | |
---|---|---|---|
LCN | 118.5 | 455.3 | 73.9% |
EasyTransaction | 166.2 | 346.4 | 52.0% |
可以看到由於LCN的事務處理機制導致事務完成前會鎖定所有的分散式資源,導致在此場景下效能衰減比較大。
可靠性測試
可靠性測試選取效能測試中表現較好的LCN與EasyTransaction進行。可靠性測試以壓測的形式,最終評估壓測過程中的全部訂單資料、支付資料、庫存資料是否與實際完成的交易結果保持一致。
可靠性測試場景說明
在可靠性測試中會通過一定的規則丟擲異常的方式來製造事務異常,來驗證事務異常場景下,分散式事務的資料最終一致性。
異常規則如下:
- 在支付服務中對於總價格為100的資料丟擲異常
- 在庫存服務中對於商品ID為100的資料丟擲異常
商品價格價格為1-10000之間隨機,商品ID為1-1000之間隨機,購買數量也通過一定的規則隨機產生。
可靠性測試總髮送100萬個請求,記錄所有成功請求的引數中的商品價格以及商品個數等資訊,最終在查詢三個服務各自資料庫中的資料,看銷售金額以及售出商品個數與請求引數總的結果是否一致。
EasyTransaction
統計記錄的所有成功請求的資料,總商品價格是3000172719,查詢訂單服務的資料庫中總銷售金額為3000172719,在支付服務資料庫中扣除銷售金額為100的錯誤資料後,銷售金額也為3000172719,三者一致。
統計記錄的所有成功請求的資料,總購買數量1799058,查詢訂單服務的資料庫中商品總售出數量是1799058。在庫存服務資料庫1000種商品總扣減的庫存數也是1799058,三者一致。
LCN
統計記錄的所有成功請求的資料,總商品價格是4375046335,查詢訂單服務的資料庫中總銷售金額為4375046335,在支付服務資料庫中銷售金額也為4375046335,三者一致。
統計記錄的所有成功請求的資料,總購買數量2624655,查詢訂單服務的資料庫中商品總售出數量是2624655。在庫存服務資料庫1000種商品總扣減的庫存數也是2624655,三者一致。
測試通過統計訂單資料庫、支付資料庫、庫存資料庫的資料,來檢測分散式事務最終一致性。經過測試發現EasyTransaction與LCN都能可靠的完成分散式事務,達到最終一致性。
總結
本次測試中,效能方面表現亮眼的是LCN和EasyTransaction,對tcc-transaction和Hmily來說,在效能優化方面還有很大的改進空間;在可靠性方面,LCN與EasyTransaction都表現不錯。
LCN總結
tx-lcn是LCN(lock,cancel,notify)的事務模式的實現
- 效能優秀
- 可靠性強
- 程式碼入侵性小
在本次對比的所有框架中,LCN實現的分散式事務處理模式,編碼複雜性和入侵程式碼量最低。
- 需額外部署tx-manager服務節點。
- 由於需要lock資源這種處理方式,如果集中更新某幾個熱門商品時,LCN的效能衰減量大於TCC模式。
- 服務超時時,會造成其他服務的資源被鎖住,比如支付服務超時過程中,相關商品庫存會一直無法操作。
EasyTransaction總結
基於Spring事務為基礎,實現了多種分散式事務處理模式並提供擴充套件介面(本次僅對TCC模式進行了測試)
- 針對遠端呼叫採用多執行緒併發處理的模式,效能優化較好
- 可靠性強
- 整合簡單,無需額外部署事務管理節點
- 對比其他框架,入侵性和編碼量是偏大的
- RPC請求超時處理尚未實現
tcc-transaction總結
實現TCC模式
通過註解的形式宣告TCC的的confirm與cancel方法,程式碼入侵性較小。
- 對資料的效能壓力太大,操作響應時間長,頻寬佔用高,成為了效能瓶頸。
- 分散式事務中RPC請求是序列處理,請求響應時間長
Hmily總結
實現TCC模式
通過註解的形式宣告TCC的的confirm與cancel方法,程式碼入侵性較小。
- 多執行緒的鎖機制有待優化。
- 分散式事務中RPC請求序列處理,請求的響應時間長
ByteTCC總結
實現TCC模式
很遺憾,因為demo程式碼的問題再加上我們時間有限,本次未能對此框架完成有效測試。希望作者有空改善一下demo程式碼的問題,我們會在後續補充本框架的測試結果。
分散式事務與本地事務對比
經過測試,使用以上幾種框架實現分散式事務的效能比本地事務的效能要差的多,從這一結果可以看出不通過訊息佇列實現的分散式事務處理效能都遠不如本地事務,從這個層面也進一步說明了微服務設計中應儘量避免分散式事務的必要性。
在下一輪測試中我們將測試基於訊息中介軟體的非同步化會分散式事務的效能方面會有怎樣的改善。