每秒1w+分散式事務--dtm的Redis儲存效能測試分析

葉東富發表於2021-12-27

概述

之前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

關注【分散式事務】公眾號,獲取更多分散式事務相關知識,同時可以加入我們的社群

相關文章