【Redis】Redis 性能测试
使用 Redis 官方提供的 redis-benchmark
工具可以对 Redis 进行性能测试。
Redis-benchmark
测试的命令有:
PING_INLINE
:Ping 命令,使用inline
协议。PING_MBULK
:Ping 命令,使用multibulk
协议。SET
:设置一个 Key 的值。GET
:获取一个 Key 的值。INCR
:使一个 Key 的值加一。LPUSH
:将一个数从左边压入队列。RPUSH
:将一个数从右边压入队列。LPOP
:将一个数从左边出队。RPOP
:将一个数从右边出队。SADD
:向集合添加一个元素。HSET
:设置哈希表的一个字段的值。SPOP
:从集合取出一个元素。ZADD
:向 ZSET 添加一个元素。ZPOPMIN
:从 ZSET 取出最小元素。LRANGE_100
:返回列表左边前 100 个元素。LRANGE_300
:返回列表左边前 300 个元素。LRANGE_500
:返回列表左边前 500 个元素。LRANGE_600
:返回列表左边前 600 个元素。MSET
:原子地一次性设置多个 Key 的值。
inline
和multibulk
是 Reids 定义的数据解析协议。inline
是老协议了,现在主要用在像 redis-cli 这种做简单的调试和处理中;程序客户端用的基本都是multibulk
协议,它支持让空格和回车在 Redis 里面正确表达出来。
可以看到,只读的操作是 PING
、GET
、LRANGE
这三个类别,其他操作都需要进行写操作。
单机测试
Docker 与 Host
对比一下 Docker 中与宿主机中 Redis 的性能差异,H 指 Host,C 指 Container。
参数:
- 请求数量:100_000
- 连接数量: 50
- 数据大小: 3Byte
- 保持连接: 开启
- RDB : 900 1; 300 10; 60 10000
- AOF : 关闭
- 多线程 : 关闭
读操作对比:
| Test | Host QPS | Container QPS | QPS ratio | Host Latency | Container Latency | La Ratio |
|--------------:|----------:|--------------:|----------:|-------------:|------------------:|---------:|
| `GET` | 171821.30 | 42301.18 | 4.06 | 0.160 | 1.091 | 0.146 |
| `PING_INLINE` | 174520.06 | 40112.31 | 4.35 | 0.162 | 1.151 | 0.140 |
| `PING_MBULK` | 154559.50 | 42176.30 | 3.66 | 0.188 | 1.092 | 0.172 |
| `LRANGE_100` | 93196.65 | 34094.78 | 2.73 | 0.304 | 1.288 | 0.236 |
| `LRANGE_300` | 30432.14 | 21427.04 | 1.42 | 0.897 | 1.726 | 0.519 |
| `LRANGE_500` | 21399.53 | 15850.37 | 1.35 | 1.264 | 2.136 | 0.591 |
| `LRANGE_600` | 18726.59 | 14269.41 | 1.31 | 1.542 | 2.284 | 0.675 |
GET
请求在主机中能达到十七万,在容器中能达到四万以上,算是比较好的成绩了,要注意我这里的 Host 实际上是 WSL2 虚拟机,因此容器指的是 WSL2 中的 Docker Container。
写操作对比:
| Test | Host QPS | Container QPS | QPS ratio | Host Latency | Container Latency | La Ratio |
|--------------:|----------:|--------------:|----------:|-------------:|------------------:|---------:|
| `SET` | 174216.03 | 42194.09 | 4.12 | 0.166 | 1.094 | 0.151 |
| `INCR` | 194552.53 | 40799.68 | 4.76 | 0.146 | 1.134 | 0.128 |
| `LPUSH` | 188679.25 | 41152.26 | 4.58 | 0.148 | 1.125 | 0.131 |
| `RPUSH` | 190476.20 | 41169.21 | 4.62 | 0.147 | 1.123 | 0.130 |
| `LPOP` | 176991.16 | 41017.23 | 4.31 | 0.157 | 1.128 | 0.139 |
| `RPOP` | 176991.16 | 41237.11 | 4.29 | 0.155 | 1.123 | 0.138 |
| `SADD` | 181488.20 | 40833.00 | 4.44 | 0.151 | 1.131 | 0.133 |
| `HSET` | 165016.50 | 40600.89 | 4.06 | 0.165 | 1.134 | 0.145 |
| `SPOP` | 176678.45 | 41407.87 | 4.26 | 0.154 | 1.114 | 0.138 |
| `ZADD` | 214132.77 | 40633.89 | 5.26 | 0.133 | 1.135 | 0.117 |
| `ZPOPMIN` | 173310.22 | 41390.73 | 4.18 | 0.161 | 1.116 | 0.144 |
| `LPUSH` | 158730.16 | 40650.41 | 3.90 | 0.184 | 1.137 | 0.161 |
| `MSET` | 138121.55 | 38565.37 | 3.58 | 0.312 | 1.203 | 0.259 |
写操作的差异更加明显,所以 Redis 最好是不要部署在容器中,平时拿来练手就可以。
为什么不补充 Windows 真机的测试结果呢?是因为 Redis 在 Win 下表现并不是特别好,速度差不多只有 Docker 的一倍,比 WSL 还差。
Rdb 开关对比
对比一下 Rdb 开启与关闭的速度差异。
参数:
- 请求数量:100_000
- 连接数量: 50
- 数据大小: 3Byte
- 保持连接: 开启
- RDB : 900 1; 300 10; 60 10000 或 关闭
- AOF : 关闭
- 多线程 : 关闭
读操作速度基本相同就不用看了,重点关注写操作:
| Test | QPS | RDB QPS | QPS ratio | Latency | RDB Latency | La Ratio |
|--------:|---------:|---------:|----------:|--------:|------------:|---------:|
| SET | 37664.79 | 37147.11 | 1.013 | 1.236 | 1.252 | 0.987 |
| INCR | 36995.93 | 36995.93 | 1.000 | 1.258 | 1.254 | 1.003 |
| LPUSH | 35549.23 | 37119.52 | 0.957 | 1.312 | 1.255 | 1.045 |
| RPUSH | 36523.01 | 36656.89 | 0.996 | 1.277 | 1.269 | 1.006 |
| LPOP | 35893.75 | 35919.54 | 0.999 | 1.299 | 1.296 | 1.002 |
| RPOP | 36630.04 | 36549.71 | 1.002 | 1.275 | 1.273 | 1.001 |
| SADD | 36429.88 | 36913.99 | 0.986 | 1.278 | 1.259 | 1.015 |
| HSET | 36114.12 | 36643.46 | 0.985 | 1.288 | 1.268 | 1.015 |
| SPOP | 36764.71 | 36710.72 | 1.001 | 1.267 | 1.266 | 1.000 |
| ZADD | 36179.45 | 35932.45 | 1.006 | 1.283 | 1.294 | 0.991 |
| ZPOPMIN | 36643.46 | 36710.72 | 0.998 | 1.268 | 1.266 | 1.001 |
| LPUSH | 36205.65 | 36205.65 | 1.000 | 1.285 | 1.282 | 1.002 |
| MSET | 34806.82 | 34566.2 | 1.006 | 1.341 | 1.351 | 0.992 |
| Avg | - | - | 0.998 | - | - | 1.003 |
可以看出,二者速度差异并不明显,因为 Rdb 本来就不是即时快照,基本不会对性能造成太多影响。
AOF 开关对比
对比一下 AOF 开启与关闭的差异,还有各种模式的差异。
参数:
- 请求数量:500_000
- 连接数量: 50
- 数据大小: 3Byte
- 保持连接: 开启
- RDB : 900 1; 300 10; 60 10000
- AOF : 关闭 /
no
/everysec
/always
- 多线程 : 关闭
QPS:
| TEST | OFF | NO | Every Sec | Always | Ratio |
|--------:|---------:|---------:|----------:|---------:|--------------------------:|
| SET | 36683.79 | 30829.94 | 31098.40 | 2778.40 | 13.20 : 11.10 : 11.19 : 1 |
| INCR | 36435.18 | 28082.00 | 31293.03 | 5991.11 | 6.08 : 4.69 : 5.22 : 1 |
| LPUSH | 35803.79 | 27997.09 | 30644.77 | 3421.54 | 10.46 : 8.18 : 8.96 : 1 |
| RPUSH | 35270.88 | 27942.33 | 30994.30 | 2879.06 | 12.25 : 9.71 : 10.77 : 1 |
| LPOP | 32731.08 | 27311.96 | 30929.11 | 2377.05 | 13.77 : 11.49 : 13.01 : 1 |
| RPOP | 32632.82 | 27783.95 | 31135.19 | 2792.09 | 11.69 : 9.95 : 11.15 : 1 |
| SADD | 32918.56 | 33200.53 | 36480.37 | 37103.00 | 0.89 : 0.89 : 0.98 : 1 |
| HSET | 29647.20 | 28494.90 | 30847.06 | 6031.22 | 4.92 : 4.72 : 5.11 : 1 |
| SPOP | 32754.67 | 34698.12 | 36710.72 | 37094.74 | 0.88 : 0.94 : 0.99 : 1 |
| ZADD | 32356.18 | 35714.29 | 36093.27 | 35844.86 | 0.90 : 1.00 : 1.01 : 1 |
| ZPOPMIN | 32877.43 | 36129.78 | 36659.58 | 36648.83 | 0.90 : 0.99 : 1.00 : 1 |
| LPUSH | 33064.41 | 30415.48 | 30723.85 | 6216.04 | 5.32 : 4.89 : 4.94 : 1 |
| MSET | 33824.92 | 27719.26 | 28282.14 | 5615.39 | 6.02 : 4.94 : 5.04 : 1 |
时延:
| TEST | OFF | NO | Every Sec | Always | Ratio |
|--------:|------:|------:|----------:|-------:|:------------------------|
| SET | 1.269 | 1.522 | 1.509 | 17.893 | 1 : 1.20 : 1.19 : 14.10 |
| INCR | 1.276 | 1.667 | 1.500 | 8.238 | 1 : 1.31 : 1.18 : 6.46 |
| LPUSH | 1.3 | 1.673 | 1.532 | 14.494 | 1 : 1.29 : 1.18 : 11.15 |
| RPUSH | 1.32 | 1.677 | 1.514 | 17.247 | 1 : 1.27 : 1.15 : 13.07 |
| LPOP | 1.421 | 1.715 | 1.516 | 20.934 | 1 : 1.21 : 1.07 : 14.73 |
| RPOP | 1.426 | 1.688 | 1.507 | 17.781 | 1 : 1.18 : 1.06 : 12.47 |
| SADD | 1.411 | 1.399 | 1.275 | 1.253 | 1 : 0.99 : 0.90 : 0.89 |
| HSET | 1.565 | 1.644 | 1.519 | 8.189 | 1 : 1.05 : 0.97 : 5.23 |
| SPOP | 1.417 | 1.338 | 1.267 | 1.255 | 1 : 0.94 : 0.89 : 0.89 |
| ZADD | 1.435 | 1.302 | 1.289 | 1.299 | 1 : 0.91 : 0.90 : 0.91 |
| ZPOPMIN | 1.411 | 1.285 | 1.267 | 1.268 | 1 : 0.91 : 0.90 : 0.90 |
| LPUSH | 1.407 | 1.542 | 1.526 | 7.942 | 1 : 1.10 : 1.08 : 5.64 |
| MSET | 1.381 | 1.704 | 1.671 | 8.799 | 1 : 1.23 : 1.21 : 6.37 |
可以看到 Every Second
模式与关闭 AOF 的效果接近,反倒是 NO
模式性能比 Every Second
效果要差,这一点比较出乎我的意料,可能是容器的系统 flush
机制稍有不同吧,接下来有时间会进行时机测试对比验证。
TODO: 实机验证
no
模式是否比every second
差。
可以看到 always
模式简直致命,并发度甚至可以拿事务型数据库来与之争锋了,因此非常不推荐使用 always
模式。
主从复制测试
主要是测试主从复制模式下,Master 的读写性能与单机的读写性能差异。
| TEST | M QPS | QPS | QPS Ratio | M latency | latency | La Ratio |
|------------:|---------:|---------:|----------:|:----------|:--------|---------:|
| PING_INLINE | 39525.69 | 37523.45 | 1.053 | 1.175 | 1.24 | 0.948 |
| PING_MBULK | 38565.37 | 39416.63 | 0.978 | 1.197 | 1.173 | 1.020 |
| GET | 39635.36 | 42229.73 | 0.939 | 1.164 | 1.094 | 1.064 |
| LRANGE_100 | 32701.11 | 33322.23 | 0.981 | 1.348 | 1.323 | 1.019 |
| LRANGE_300 | 20863.76 | 21253.99 | 0.982 | 1.763 | 1.756 | 1.004 |
| LRANGE_500 | 15586.04 | 15659.25 | 0.995 | 2.173 | 2.197 | 0.989 |
| LRANGE_600 | 13791.20 | 14409.22 | 0.957 | 2.36 | 2.311 | 1.021 |
| SET | 30797.66 | 35087.72 | 0.878 | 1.53 | 1.333 | 1.148 |
| INCR | 32509.75 | 35360.68 | 0.919 | 1.447 | 1.318 | 1.098 |
| LPUSH | 31635.56 | 34411.56 | 0.919 | 1.491 | 1.359 | 1.097 |
| RPUSH | 31036.62 | 34891.84 | 0.890 | 1.519 | 1.341 | 1.133 |
| LPOP | 30543.68 | 34129.69 | 0.895 | 1.542 | 1.369 | 1.126 |
| RPOP | 29877.50 | 34506.55 | 0.866 | 1.577 | 1.354 | 1.165 |
| SADD | 39047.25 | 41034.06 | 0.952 | 1.183 | 1.128 | 1.049 |
| HSET | 29214.14 | 34258.31 | 0.853 | 1.615 | 1.36 | 1.188 |
| SPOP | 41254.12 | 40600.89 | 1.016 | 1.121 | 1.138 | 0.985 |
| ZADD | 39385.59 | 38744.67 | 1.017 | 1.173 | 1.192 | 0.984 |
| ZPOPMIN | 37285.61 | 39077.77 | 0.954 | 1.239 | 1.179 | 1.051 |
| LPUSH | 31172.07 | 33863.87 | 0.921 | 1.513 | 1.379 | 1.097 |
| MSET | 26123.30 | 30093.29 | 0.868 | 1.824 | 1.567 | 1.164 |
可以看到,对于大部分写操作,大概有 10% 的性能损失。
集群测试
测试集群模式与单例模式下性能的差异。由于集群采用的是 Docker 内网集群,因此测试都转移到容器内进行测试。或许是少了 Docker 的网络转发,测试速度相比于在宿主机测试快了非常多。
| TEST | C QPS | QPS | QPS Ratio | C latency | latency | La Ratio |
|------------:|----------:|----------:|----------:|:----------|:--------|---------:|
| PING_INLINE | 199203.20 | 124533.01 | 1.600 | 0.113 | 0.227 | 0.498 |
| PING_MBULK | 200000.00 | 120192.30 | 1.664 | 0.115 | 0.249 | 0.462 |
| GET | 199600.80 | 132978.73 | 1.501 | 0.107 | 0.206 | 0.519 |
| LRANGE_100 | 133155.80 | 63211.12 | 2.107 | 0.186 | 0.438 | 0.425 |
| LRANGE_300 | 57077.62 | 27225.70 | 2.096 | 0.41 | 0.989 | 0.415 |
| LRANGE_500 | 44385.27 | 19531.25 | 2.273 | 0.574 | 1.386 | 0.414 |
| LRANGE_600 | 36324.01 | 17009.70 | 2.135 | 0.667 | 1.6 | 0.417 |
| SET | 200000.00 | 152905.20 | 1.308 | 0.171 | 0.196 | 0.872 |
| INCR | 200000.00 | 158478.61 | 1.262 | 0.158 | 0.172 | 0.919 |
| LPUSH | 200000.00 | 183150.19 | 1.092 | 0.18 | 0.155 | 1.161 |
| RPUSH | 200000.00 | 155038.77 | 1.290 | 0.171 | 0.182 | 0.940 |
| LPOP | 200000.00 | 134408.59 | 1.488 | 0.174 | 0.207 | 0.841 |
| RPOP | 200000.00 | 151975.69 | 1.316 | 0.191 | 0.199 | 0.960 |
| SADD | 200000.00 | 125313.29 | 1.596 | 0.12 | 0.224 | 0.536 |
| HSET | 199600.80 | 142653.36 | 1.399 | 0.193 | 0.244 | 0.791 |
| SPOP | 199600.80 | 121065.38 | 1.649 | 0.116 | 0.227 | 0.511 |
| ZADD | 200000.00 | 140449.44 | 1.424 | 0.125 | 0.198 | 0.631 |
| ZPOPMIN | 199600.80 | 132626.00 | 1.505 | 0.117 | 0.21 | 0.557 |
| LPUSH | 199600.80 | 160771.70 | 1.242 | 0.189 | 0.187 | 1.011 |
| MSET | 133333.33 | 109409.20 | 1.219 | 0.312 | 0.395 | 0.790 |
可以看到,集群模式下,性能要优于单例模式非常多。
转载自:https://juejin.cn/post/6997120514716074014