概述
之前dtm給出了Mysql作為儲存引擎的效能測試報告,在一個普通配置的機器上,2.68w IOPS,4核8G機器上,能夠支援大約每秒900+分散式事務,能夠滿足大部分公司的業務需求。
此次帶來的是Redis儲存引擎的測試報告,在一個普通配置的機器上,能夠達到大約10800每秒的分散式事務能力,對比Mysql儲存,有10倍左右的效能提升,滿足絕大部分公司的業務需求。
下面我們來詳細說明測試的步驟,並分析其中影影響效能的各個因素。
測試環境
下面的伺服器都來自阿里雲,地區為東京(外網訪問比較方便)
Redis伺服器:ecs.hfc6 4核8G CPU主頻為3.1 GHz/3.5 GHz 內網收發包50萬PPS ubuntu 20.04
兩臺應用伺服器:ecs.hfc6 8核16G CPU主頻為3.1 GHz/3.5 GHz 內網收發包80萬PPS ubuntu 20.04 redis5.x
測試步驟:
準備好Redis
注意:涉及應用伺服器的,那麼兩臺伺服器都需要進行相關操作
在應用伺服器上面準備好Redis,這次因為考慮到極限效能,因此不採用docker安裝,而是採用apt install 安裝,執行如下命令
apt update
apt install -y redis
# 修改/etc/redis/redis.conf,找到其中的bind,改為bind 0.0.0.0
systemctl restart redis-server
配置應用伺服器
apt update
apt install -y git
git clone https://github.com/dtm-labs/dtm.git && cd dtm && git checkout 5907f99 && cd bench && make
配置dtm
修改 dtm目錄下的conf.sample.yml,配置使用Redis,例如:
Store:
Driver: 'redis'
Host: 'redis ip'
Port: 6379
# 另外再把ExamplesDB裡面的配置刪除,因為我們沒有安裝mysql
啟動bench伺服器
`
LOG_LEVEL=warn go run bench/main.go redis
`
啟動測試
`
ab -n 1000000 -c 10 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl"
`
獲得結果
我這看到ab的結果顯示,每秒完成的運算元量兩臺應用伺服器加總為10875
Redis效能分析
我們首先來看Redis本身的效能,影響它的因素是哪些,先看下面的這些測試資料:
`
redis-benchmark -n 300000 SET 'abcdefg' 'ddddddd'
`
每秒完成的請求數10w
`
redis-benchmark -h 內網其他主機IP -p 6379 -n 300000 SET 'abcdefg' 'ddddddd'
`
每秒完成的請求數10w
從這上面的兩個結果看,本地Redis測試和遠端Redis測試,效能差異並不明顯。我也測試過其他更多的命令,也未發現明顯差異,因此下面主要就測試本地Redis效能,不再比較本地和遠端的差別。
`
redis-benchmark -n 300000 EVAL "redis.call('SET', 'abcdedf', 'ddddddd')" 0
`
Lua指令碼每秒完成的請求數10w
`
redis-benchmark -n 300000 EVAL "redis.call('SET', KEYS[1], ARGS[1])" 1 'aaaaaaaaa' 'bbbbbbbbbb'
`
Lua指令碼每秒完成的請求數10w
`
redis-benchmark -n 3000000 -P 50 SET 'abcdefg' 'ddddddd'
`
走Pipeline的話,每秒完成的請求數150w,這個效能對比單個Set操作有大幅提升。從這個資料和單個操作的對比看,Redis本身記憶體操作開銷不大,很多的開銷花在了網路IO上,因此批量任務能夠大幅提升吞吐量
`
redis-benchmark -n 300000 EVAL "for k=1, 10 do; redis.call('SET', KEYS[1], ARGS[1]); end" 1 'aaaaaaaaa' 'bbbbbbbbbb'
`
我們在Lua內部,連續執行10次Set,每秒完成的請求數6.1w,和只執行1次Set差別沒有很大。這個結果在我們的預期之內,因為前面Pipeline的結果顯示Redis的記憶體操作開銷大幅小於網路。
`
dtm效能分析
dtm需要跟蹤全域性分散式事務的進度,我們以Saga舉例,大概涉及以下操作:
- 儲存事務資訊,含全域性事務、事務分支、還有查詢過期事務的索引,dtm用一個Lua指令碼來完成這些操作
- 每個事務分支完成時,修改事務分支狀態。由於修改狀態時,需要確認全域性事務未回滾,避免回滾中的事務還往前執行,因此dtm也用一個Lua指令碼來完成
- 全域性事務完成,修改全域性事務為成功,此時也需要避免已超時回滾中的事務被覆蓋,也是一個Lua指令碼
那麼一個具備兩個事務分支的全域性事務在Redis上的理論開銷大約是4個Lua指令碼的開銷,那麼從前面每秒能夠完成大約6w個簡單Lua指令碼來看,每秒最理想能夠完成1.5w個分散式事務。由於實際的Lua指令碼比我們測試的更復雜,傳輸的資料量更大,因此最終每秒完成1.08w個事務,已經是差不多的效能極限值。當達到1.08w每秒的事務效能時,觀測到Redis的CPU已經是100%,到了效能瓶頸。
展望
每秒1w事務已經是非常高的效能,足夠應對絕大多數的場景。包括訊息佇列、秒殺等。
當Redis能夠支撐這麼大的事務量時,如果是長時間這麼大的事務量,那麼redis的儲存空間很快就不夠了,後續可能新增選項,允許及時清理掉已完成的事務
未來dtm的效能是否還能提高?我們可以從兩方面看:
一個是在目前單程式的情況下,dtm能夠達到1w事務每秒,在redis6.0上,官方的資料顯示,4CPU效能大約提升150%,這樣的話dtm預計能夠支撐2.5w事務每秒。
另一個是dtm往叢集的方向發展,提供叢集能力,允許動態擴容等。這方面需要看未來的使用情況,再做相關規劃。
專案地址
關於分散式事務更多的理論知識與實踐,可以訪問以下專案和公眾號:
https://github.com/dtm-labs/dtm
關注【分散式事務】公眾號,獲取更多分散式事務相關知識,同時可以加入我們的社群