概述
redis-benchmark
命令是一个用于测试 redis 性能的基准测试工具。在我们的源代码编译安装环境中,它位于这个路径位置:
Shell > ls -lhS /usr/local/redis/bin/
-rwxr-xr-x 1 root root 19M 10月 11 11:39 redis-server
-rwxr-xr-x 1 root root 9.8M 10月 11 11:39 redis-cli
-rwxr-xr-x 1 root root 9.1M 10月 11 11:39 redis-benchmark
lrwxrwxrwx 1 root root 12 10月 11 11:39 redis-check-aof -> redis-server
lrwxrwxrwx 1 root root 12 10月 11 11:39 redis-check-rdb -> redis-server
lrwxrwxrwx 1 root root 12 10月 11 11:39 redis-sentinel -> redis-server
redis-benchmark
命令的用法为——redis-benchmark [OPTIONS] [COMMAND ARGS...]
命令的常用选项说明
-h <hostname>
:指定服务器的主机名,默认为 127.0.0.1-p <port>
:指定主机名的端口,默认 6379-a <password>
:指定 redis 身份验证的密码-c <client>
:指定客户端的并行连接数,默认50。基准测试的重要选项。-n <requests>
:总的请求数,默认 100000。基准测试的重要选项-d <size>
:以 byte 为单位指定 set/get 值的数据大小--dbnum <db>
:指定使用的 db 号,默认使用 0 号库--threads <num>
:启用多线程模式。--enable-tracking
:在开始基准测试之前发送CLIENT TRACKING。-k <boolean>
:是否保持连接。值为1,保持连接;值为0,重新连接。默认值为1-r <keyspacelen>
:对 set/get/incr 命令使用随机 key;对 sadd 命令使用随机 value;对 zadd 命令使用随机成员和分数。这里的 "keyspacelen" 表示使用的数量-P <numreq>
:管道请求,默认值为 1,即无管道-q
:安静输出,即仅显示每秒的查询数--csv
:以 csv 格式进行输出-l
:开启循环基准测试,这将一直运行测试。-t <tests>
:以逗号分隔的命令列表-I
:等待模式。-x
:从标准输入(stdin)中读取最后一个参数
使用基准测试之前的配置文件调整
在前面《Redis基础篇06 — 配置文件详解(一)》和《Redis基础篇07 — 配置文件详解(二)》我们提到了这两个重要参数:
- tcp-backlog 511 – 这里定义三次握手全连接队列的大小。全连接队列的大小由两部分决定——listen 函数里的 backlog 以及 Linux 内核参数 /proc/sys/net/core/somaxconn,最终的队列大小由数字最小的那个来决定
- maxclients 10000 – 表示 redis 可并发处理的客户端连接数量。若达到了最大连接数,则会拒绝新来的连接并返回异常信息("max number of clients reached")
Q:在 GNU/Linux 发行版中,常常有一句话——「一切皆文件」,那什么是文件描述符?
内核为了高效管理对已被打开的文件创建的索引,用于指向被打开的文件,所有 IO 操作的系统调用都通过文件描述符。文件描述符是一个非负整数,用于标明每一个被进程所打开的文件。在 Windows 系统中,这个东西叫句柄。
文件描述符需要和 inode 做区分。Linux 内核会为每一个文件分配一个唯一的 ID号—— inode(比如 硬链接文件的 inode 是完全相同的),方便内核找到该文件。但你需要知道的是,GNU/Linux 是多任务多用户的,当多个用户同时打开同一个文件时,如何管理文件的偏移量就成为了一个问题(因为每个用户所执行的操作都不是一样的),所有引入了一个叫做文件描述符(File descriptor)的东西,来为每一个用户服务。每个用户每次打开一个文件,就产生一个文件描述符,多次打开就产生多个文件描述符,它们之间一 一对应。所以文件的 inode 和文件描述符是这样一种关系——一个 inode 文件可拥有多个文件描述符,多个文件描述符可指向同一个 inode 文件。
文件描述符有用户级别和系统级别:
- 系统级别 –
cat /proc/sys/fs/file-max
,这里限制的是所有用户打开文件描述符的总和。其值由系统自动计算,通常为内存(以KB单位)的 10% 左右 - 用户级别 – 通过修改
/etc/security/limits.conf
文件来限制。默认情况下,所有单个用户的文件描述符为 1024
# 查看当前登录用户可使用文件描述符的上限。
Shell > ulimit -n
1024
由于用户级别的文件描述符为 1024 ,所有你在 redis.conf 中配置 "maxclients 10000" 是不起作用的。还有一点要注意!当你为 maxclients 配置了起作用的值,其实际可处理的客户端连接数需要在其基础上减32(因为有一些文件描述符需要提供给 redis 内部使用);当使用的是 redis cluster 时,每个节点还需要占用 2 个连接(一进一出)。
为了发挥最大性能,我们来更改全连接队列的大小和可并发处理的最大客户端连接数,以下为操作步骤:
# 1. 修改 redis 的全连接队列大小
## 查看内核的全连接队列大小
Shell > cat /proc/sys/net/core/somaxconn
2048
## 变更 redis 的全连接队列大小
Shell > vim /usr/local/redis/conf/redis.conf
...
tcp-backlog 1024
...
-----------------------------------------------
# 2. 修改 redis 可处理的最大客户端连接数
## 查看系统级的总的文件描述符数量
Shell > cat /proc/sys/fs/file-max
366626
## 查看当前登录用户可使用的文件描述符上限
Shell > ulimit -n
1024
## 永久修改单个用户所拥有的文件描述符上限
Shell > vim /etc/security/limits.conf
...
* soft nofile 100000
* hard nofile 100000
...
## 重启生效
Shell > reboot
## 使用 root 用户登录,查看文件描述符上限
Shell > ulimit -n
100000
## 修改 redis 配置文件
Shell > vim /usr/local/redis/conf/redis.conf
...
maxclients 80000
...
-----------------------------------------------
# 3. 启动 redis
Shell > /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
使用 redis-benchmark
Shell > /usr/local/redis/bin/redis-benchmark -h 192.168.100.3 -p 6379 -a MyPassword -c 500 -n 70000 -r 1000 --dbnum 5
由于输出的文本很长,这里简单说明。基准测试会将一个一个命令进行测试,大致有这么几个部分:
- ====== PING_INLINE ======
- ====== PING_MBULK ======
- ====== SET ======
- ====== GET ======
- ====== INCR ======
- ====== LPUSH ======
- ====== RPUSH ======
- ====== LPOP =======
- ====== RPOP ======
- ====== SADD ======
- ====== HSET ======
- ====== SPOP ======
- ====== ZADD ======
- ====== ZPOPMIN ======
- ====== LPUSH (needed to benchmark LRANGE) ======
- ====== LRANGE_100 (first 100 elements) ======
- ====== LRANGE_300 (first 300 elements) ======
- ====== LRANGE_500 (first 500 elements) ======
- ====== LRANGE_600 (first 600 elements) ======
- ====== MSET (10 keys) ======
- ====== XADD ======
每一部分的结构由 4 块组成,我们拿 ====== SET ====== 这一部分来说明。
第一块
输出如下:
====== SET ======
70000 requests completed in 1.28 seconds
500 parallel clients
3 bytes payload
keep alive: 1
host configuration "save": 3600 1 300 100 60 10000
host configuration "appendonly": no
multi-thread: no
70000请求数在 1.28 秒内完成;
500 个并发客户端;
3 byte ,即 -d 选项的默认值;
keep alive ,即 -k 选项的默认值;
host configuration "save" 表示的是持久化的一些条件,和配置文件中的 save 3600 1 300 100 60 10000 有关;
host configuration "appendonly" 表示是否启用了 AOF(Append Only File) 持久化方案;
multi-thread 表示是否启用了多线程
第二块
Latency by percentile distribution:
0.000% <= 3.143 milliseconds (cumulative count 2)
50.000% <= 6.487 milliseconds (cumulative count 35097)
75.000% <= 7.663 milliseconds (cumulative count 52540)
87.500% <= 8.295 milliseconds (cumulative count 61325)
93.750% <= 8.799 milliseconds (cumulative count 65656)
96.875% <= 9.495 milliseconds (cumulative count 67819)
98.438% <= 11.095 milliseconds (cumulative count 68909)
99.219% <= 13.023 milliseconds (cumulative count 69454)
99.609% <= 26.159 milliseconds (cumulative count 69727)
99.805% <= 29.871 milliseconds (cumulative count 69864)
99.902% <= 31.695 milliseconds (cumulative count 69932)
99.951% <= 32.543 milliseconds (cumulative count 69966)
99.976% <= 33.055 milliseconds (cumulative count 69983)
99.988% <= 33.279 milliseconds (cumulative count 69992)
99.994% <= 33.407 milliseconds (cumulative count 69996)
99.997% <= 33.471 milliseconds (cumulative count 69998)
99.998% <= 33.503 milliseconds (cumulative count 69999)
99.999% <= 33.535 milliseconds (cumulative count 70000)
100.000% <= 33.535 milliseconds (cumulative count 70000)
按请求数的百分比统计延迟的分布情况:
从0.0000% 开始;
拿出一半请求数进行统计,即50.000%的请求在 6.487 毫秒内完成;
剩余的 50% 再拿出一半进行统计,即 75.000% 的请求在 7.663 毫秒内完成;
再拿出剩余 25% 的一半进行统计,即 87.5% 的请求在8.295 毫秒内完成
....
全部请求在 33.535 毫秒内完成。
第三块
Cumulative distribution of latencies:
0.000% <= 0.103 milliseconds (cumulative count 0)
3.513% <= 4.103 milliseconds (cumulative count 2459)
20.786% <= 5.103 milliseconds (cumulative count 14550)
41.793% <= 6.103 milliseconds (cumulative count 29255)
63.203% <= 7.103 milliseconds (cumulative count 44242)
84.294% <= 8.103 milliseconds (cumulative count 59006)
95.754% <= 9.103 milliseconds (cumulative count 67028)
97.604% <= 10.103 milliseconds (cumulative count 68323)
98.447% <= 11.103 milliseconds (cumulative count 68913)
98.939% <= 12.103 milliseconds (cumulative count 69257)
99.234% <= 13.103 milliseconds (cumulative count 69464)
99.286% <= 14.103 milliseconds (cumulative count 69500)
99.339% <= 16.103 milliseconds (cumulative count 69537)
99.341% <= 17.103 milliseconds (cumulative count 69539)
99.384% <= 22.111 milliseconds (cumulative count 69569)
99.439% <= 23.103 milliseconds (cumulative count 69607)
99.499% <= 24.111 milliseconds (cumulative count 69649)
99.550% <= 25.103 milliseconds (cumulative count 69685)
99.607% <= 26.111 milliseconds (cumulative count 69725)
99.654% <= 27.103 milliseconds (cumulative count 69758)
99.710% <= 28.111 milliseconds (cumulative count 69797)
99.761% <= 29.103 milliseconds (cumulative count 69833)
99.819% <= 30.111 milliseconds (cumulative count 69873)
99.871% <= 31.103 milliseconds (cumulative count 69910)
99.924% <= 32.111 milliseconds (cumulative count 69947)
99.980% <= 33.119 milliseconds (cumulative count 69986)
100.000% <= 34.111 milliseconds (cumulative count 70000)
按照 1 毫秒间隔统计请求的百分比情况。
第四块
Summary:
throughput summary: 54602.19 requests per second
latency summary (msec):
avg min p50 p95 p99 max
6.661 3.136 6.487 8.967 12.287 33.535
吞吐量:每秒处理 54602.19 个请求(也就是常说的 RPS,有些资料也称 QPS)
延迟总结(毫秒为单位):avg表示平均处理每个请求的耗时;min 表示处理请求的最小耗时;p50表示处理50%的请求数所消耗的时间;p95表示处理95%的请求数所消耗的时间;p99表示处理99%的请求数所消耗的时间;max 表示处理请求的最大耗时。
如果你不想看到这一长串的输出内容,可以考虑使用 -q
选项;若只想测试单独的几个命令,可以使用 -t
选项。
收尾工作
最后使用连接工具将 5 号库里的 key 删除即可。