隨著微服務的大規模應用,跨微服務的分散式事務也越來越多,那麼分散式事務的效能究竟怎麼樣?效能會下降多少?能否滿足業務需求?這些指標關係到分散式事務能否順利的引入到生產應用,是大家非常關心的問題。
本文嘗試深入分析分散式事務帶來的額外開銷,應用中的哪些因素會影響最終的效能,瓶頸點在哪裡,如何提升效能。本文以支援多語言的分散式事務管理器https://github.com/yedf/dtm的saga事務作為效能測試的樣本,對效能測試的結果,進行深度剖析。
測試環境
機型 | CPU/記憶體 | 儲存 | 系統 | Mysql |
---|---|---|---|---|
阿里雲ecs.c7.xlarge | 4核8G | 500G ESSD IOPS 26800 | Ubuntu 20.04 | Docker mysql:5.7 |
測試過程
# 在dtm目錄下
docker-compose -f helper/compose.mysql.yml up -d # 啟動Mysql
# 執行sysbench對mysql進行測試
sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 prepare
sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 run
go run app/main.go bench > /dev/nul # 啟動dtm的bench服務,日誌較多,重定向到nul裝置
bench/run-dtm.sh # 新啟動命令列,執行dtm相關的各項測試
PS:如果您需要動手進行測試,建議您購買香港或國外的主機,這樣相關的github、docker訪問會快很多,能夠快速搭建好環境。我在國內購買的主機,訪問github和docker,非常慢,有時連線不上,無法順暢進行測試。
測試指標
我們會對以下幾個指標進行對比:
- Global-TPS:使用者視角下,完成了多少個全域性事務。
- DB-TPS:各項測試中,在DB層面完成的事務數量
- OPS:各項測試中,完成了多少個SQL語句
結果對比
Mysql | 無DTM-2SQL | DTM-2SQL | DTM-2SQL-Barrier | 無DTM-10SQL | DTM-10SQL | DTM-10SQL-Barrier | |
---|---|---|---|---|---|---|---|
Global-TPS | - | 1232 | 575 | 531 | 551 | 357 | 341 |
DB-TPS | 2006 | 2464 | 2300 | 2124 | 1102 | 1428 | 1364 |
OPS | 12039 | 4928 | 5750 | 6372 | 10620 | 9282 | 9548 |
Mysql效能
我們首先用測試了Mysql自身的效能。在DTM的這次效能測試中,寫操作較多,因此我們這次主要對Mysql的寫進行了效能測試。
我們採用了sysbench中的oltp_write_only基準,在這個基準中,每個事務包含6個寫SQL(有insert/update/delete)。
在這個基準下,每秒完成的事務數量大約為2006,完成SQL數量大約為為12039。這兩項結果,會在後續的DTM相關測試中引用。
DTM測試
分散式事務中涉及的事務模式有多種,我們選取一個有代表性的簡單Saga模式作為代表,分析分散式事務DTM的效能。
我們選取的Saga事務,包含兩個子事務,一個是TransOut轉出餘額,一個是TransIn轉入餘額。轉入轉出各包含兩個Sql,分別是更新餘額和記錄流水。
無DTM-2SQL
我們首先測試不採用DTM的情況,也就是直接呼叫TransOut和TransIn,測試結果是每秒完成了1232個全域性事務。每個全域性事務包含轉出和轉入兩個子事務,因此DB-TPS為2464,然後每個子事務又包含兩個SQL,因此總的SQL操作為4928。
這個結果對比MYSQL,DB-TPS更高,而DB-SQL只有一半,主要原因為每個事務都需要將資料同步到磁碟,需要額外消耗效能,此時瓶頸主要在系統資料庫的事務能力
DTM-2SQL
我們接著測試採用DTM的情況,採用了DTM之後,一個SAGA事務的時序圖如下:
全域性事務會包括4個事務:TransIn、TransOut、儲存全域性事務+事務分支、修改全域性事務為已完成。將每個子事務分支修改為已完成也各需要一個事務,但DTM採用非同步寫進行了合併,減少了事務。
每個全域性事務包括的SQL數量為:1個儲存全域性事務、1個儲存分支、1個讀所有分支、2個修改分支為完成、1個修改全域性事務為完成,一共6個額外的SQL,加上原本子事務的4個SQL是10個。
測試結果中,每秒完成全域性事務數為575,那麼DB-TPS為2300,OPS為5750,對比前面不採用DTM的方案,DB-TPS略有下降,OPS有一定的上升,瓶頸還是在系統資料庫
DTM-2SQL-Barrier
加入了子事務屏障後,每個子事務分支會多一個insert語句,每個全域性事務對應的SQL數量為12.
測試結果中,每秒完成全域性事務數為531,那麼DB-TPS為2124,OPS為6372,對比前面DTM的方案,DB-TPS略有下降,OPS略有上升,符合預期
無DTM-10SQL
我們對壓測的資料做調整,將每個子事務裡的SQL數量,從2調整為10,將子事務中的SQL迴圈執行5次。
無DTM的壓測結果中,每秒完成的全域性事務數為551,DB-TPS為1102,OPS為10620。這個結果中,OPS與MYSQL的接近,瓶頸主要在資料庫的OPS。
DTM-10SQL
這個壓測結果中,每秒完成的全域性事務數為357,DB-TPS為1428,OPS為9282,其中OPS比無DTM的情況下降了百分之十幾,主要原因為DTM的表,有較多的欄位及索引,每個SQL的執行開銷會大一些,因此總OPS會更低。
DTM-10SQL-Barrier
測試結果中,每秒完成全域性事務數為341,那麼DB-TPS為1364,OPS為9548,對比前面DTM的方案,DB-TPS略有下降,OPS略有上升,符合預期
小結
由於分散式事務需要儲存全域性事務和分支事務的狀態,會產生額外的寫,大約是每個全域性事務產生額外4+n(子事務數量)個SQL操作,2個資料庫事務。當業務很簡單,SQL少,使用分散式事務會導致事務吞吐量下降50%;如果業務較複雜,SQL多,效能大約下降35%。下降的原因主要為全域性/分支事務狀態的儲存,產生了額外的SQL操作。
從DTM的壓測結果與MYSQL的壓測資料對比來看,DTM產生的額外開銷很小,已經最大化的利用了資料庫的能力。
一臺ecs.c7.xlarge+500G磁碟的阿里雲伺服器,安裝mysql後,大約能夠提供300~600的Global-TPS,每月費用為900元(2021年10月價格),這個成本對比提供的業務能力來說,已經很低了。
如果您需要更強勁的效能,可以購買更高配的配置,也可以在應用層部署多組DTM,兩種方案的代價並不大,足以滿足絕大部分公司的需求。
歡迎大家訪問https://github.com/yedf/dtm專案,給顆星星支援我們的工作!