Redis性能测试和慢查询操作最佳实践
简介
Redis有自带有个很好的性能测试工具redis-benchmark可以很方面的测试redis的性能。以下是这个功能的使用方法和测试参数:
Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>]
[-n <requests]> [-k <boolean>]
-h <hostname> Server hostname (default 127.0.0.1)
-p <port> Server port (default 6379)
-s <socket> Server socket (overrides host and port)
-a <password> Password for Redis Auth
-c <clients> Number of parallel connections (default 50)
-n <requests> Total number of requests (default 100000)
-d <size> Data size of SET/GET value in bytes (default 2)
-dbnum <db> SELECT the specified db number (default 0)
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD
Using this option the benchmark will expand the string __rand_int__
inside an argument with a 12 digits number in the specified range
from 0 to keyspacelen-1. The substitution changes every time a command
is executed. Default tests use this to hit random keys in the specified range.
-P <numreq> Pipeline <numreq> requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values
--csv Output in CSV format
-l Loop. Run the tests forever
-t <tests> Only run the comma separated list of tests. The test
names are the same as the ones produced as output.
测试
- 100个并发连接,100000个请求,检测host为192.168.0.11 端口为7000的redis服务器性能
[root@inspur_1 bin]# ./redis-benchmark -h 192.168.0.11 -p 7000 -c 100 -n 1000000 -a 888888
====== PING_INLINE ======
1000000 requests completed in 52.54 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.01% <= 1 milliseconds
1.52% <= 2 milliseconds
62.58% <= 3 milliseconds
83.88% <= 4 milliseconds
93.92% <= 5 milliseconds
97.50% <= 6 milliseconds
99.29% <= 7 milliseconds
99.92% <= 8 milliseconds
99.99% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 11 milliseconds
19032.76 requests per second
====== PING_BULK ======
1000000 requests completed in 51.06 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.49% <= 1 milliseconds
6.04% <= 2 milliseconds
65.88% <= 3 milliseconds
85.99% <= 4 milliseconds
94.68% <= 5 milliseconds
97.83% <= 6 milliseconds
99.44% <= 7 milliseconds
99.95% <= 8 milliseconds
99.99% <= 9 milliseconds
99.99% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 12 milliseconds
100.00% <= 13 milliseconds
100.00% <= 14 milliseconds
19585.95 requests per second
====== SET ======
1000000 requests completed in 53.21 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.61% <= 2 milliseconds
56.34% <= 3 milliseconds
79.13% <= 4 milliseconds
91.31% <= 5 milliseconds
96.58% <= 6 milliseconds
98.57% <= 7 milliseconds
99.64% <= 8 milliseconds
99.99% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 12 milliseconds
100.00% <= 13 milliseconds
100.00% <= 14 milliseconds
100.00% <= 14 milliseconds
18793.46 requests per second
====== GET ======
1000000 requests completed in 52.58 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.01% <= 1 milliseconds
1.48% <= 2 milliseconds
63.08% <= 3 milliseconds
83.86% <= 4 milliseconds
93.90% <= 5 milliseconds
97.44% <= 6 milliseconds
99.25% <= 7 milliseconds
99.92% <= 8 milliseconds
100.00% <= 9 milliseconds
100.00% <= 9 milliseconds
19017.91 requests per second
====== INCR ======
1000000 requests completed in 52.80 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.75% <= 2 milliseconds
56.60% <= 3 milliseconds
79.49% <= 4 milliseconds
91.57% <= 5 milliseconds
96.75% <= 6 milliseconds
98.71% <= 7 milliseconds
99.71% <= 8 milliseconds
99.98% <= 9 milliseconds
99.99% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 12 milliseconds
100.00% <= 13 milliseconds
100.00% <= 14 milliseconds
100.00% <= 14 milliseconds
18940.83 requests per second
====== LPUSH ======
1000000 requests completed in 51.98 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.16% <= 1 milliseconds
2.78% <= 2 milliseconds
54.04% <= 3 milliseconds
77.59% <= 4 milliseconds
90.53% <= 5 milliseconds
96.28% <= 6 milliseconds
98.47% <= 7 milliseconds
99.59% <= 8 milliseconds
99.97% <= 9 milliseconds
99.99% <= 10 milliseconds
99.99% <= 11 milliseconds
99.99% <= 12 milliseconds
99.99% <= 13 milliseconds
100.00% <= 14 milliseconds
100.00% <= 15 milliseconds
100.00% <= 16 milliseconds
100.00% <= 17 milliseconds
100.00% <= 17 milliseconds
19239.65 requests per second
====== RPUSH ======
1000000 requests completed in 52.51 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.04% <= 1 milliseconds
1.31% <= 2 milliseconds
53.95% <= 3 milliseconds
77.46% <= 4 milliseconds
90.31% <= 5 milliseconds
96.14% <= 6 milliseconds
98.40% <= 7 milliseconds
99.56% <= 8 milliseconds
99.97% <= 9 milliseconds
99.99% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 12 milliseconds
100.00% <= 12 milliseconds
19043.63 requests per second
====== LPOP ======
1000000 requests completed in 51.55 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.27% <= 1 milliseconds
3.54% <= 2 milliseconds
54.17% <= 3 milliseconds
77.57% <= 4 milliseconds
90.61% <= 5 milliseconds
96.37% <= 6 milliseconds
98.55% <= 7 milliseconds
99.64% <= 8 milliseconds
99.98% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 10 milliseconds
19397.51 requests per second
====== RPOP ======
1000000 requests completed in 52.57 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.70% <= 2 milliseconds
54.02% <= 3 milliseconds
77.94% <= 4 milliseconds
90.75% <= 5 milliseconds
96.43% <= 6 milliseconds
98.56% <= 7 milliseconds
99.65% <= 8 milliseconds
99.98% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 12 milliseconds
100.00% <= 12 milliseconds
19021.89 requests per second
====== SADD ======
1000000 requests completed in 51.85 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.01% <= 1 milliseconds
1.69% <= 2 milliseconds
63.16% <= 3 milliseconds
83.78% <= 4 milliseconds
93.82% <= 5 milliseconds
97.40% <= 6 milliseconds
99.21% <= 7 milliseconds
99.92% <= 8 milliseconds
99.99% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 10 milliseconds
19287.52 requests per second
====== HSET ======
1000000 requests completed in 51.68 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
1.07% <= 2 milliseconds
52.80% <= 3 milliseconds
77.65% <= 4 milliseconds
90.75% <= 5 milliseconds
96.40% <= 6 milliseconds
98.56% <= 7 milliseconds
99.65% <= 8 milliseconds
99.98% <= 9 milliseconds
100.00% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 11 milliseconds
19349.47 requests per second
====== SPOP ======
1000000 requests completed in 51.45 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.01% <= 1 milliseconds
1.91% <= 2 milliseconds
64.06% <= 3 milliseconds
84.62% <= 4 milliseconds
94.27% <= 5 milliseconds
97.70% <= 6 milliseconds
99.41% <= 7 milliseconds
99.95% <= 8 milliseconds
99.99% <= 9 milliseconds
100.00% <= 10 milliseconds
19434.84 requests per second
====== LPUSH (needed to benchmark LRANGE) ======
1000000 requests completed in 52.35 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.79% <= 2 milliseconds
51.89% <= 3 milliseconds
76.66% <= 4 milliseconds
90.12% <= 5 milliseconds
96.08% <= 6 milliseconds
98.38% <= 7 milliseconds
99.57% <= 8 milliseconds
99.98% <= 9 milliseconds
99.99% <= 10 milliseconds
100.00% <= 11 milliseconds
100.00% <= 11 milliseconds
19100.74 requests per second
====== LRANGE_100 (first 100 elements) ======
1000000 requests completed in 83.72 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.01% <= 2 milliseconds
0.43% <= 3 milliseconds
13.69% <= 4 milliseconds
71.26% <= 5 milliseconds
82.58% <= 6 milliseconds
89.11% <= 7 milliseconds
93.59% <= 8 milliseconds
96.70% <= 9 milliseconds
98.21% <= 10 milliseconds
99.01% <= 11 milliseconds
99.50% <= 12 milliseconds
99.86% <= 13 milliseconds
99.98% <= 14 milliseconds
100.00% <= 15 milliseconds
100.00% <= 16 milliseconds
100.00% <= 17 milliseconds
100.00% <= 17 milliseconds
11945.00 requests per second
====== LRANGE_300 (first 300 elements) ======
1000000 requests completed in 113.06 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.08% <= 2 milliseconds
6.70% <= 3 milliseconds
28.16% <= 4 milliseconds
35.29% <= 5 milliseconds
46.65% <= 6 milliseconds
63.21% <= 7 milliseconds
78.88% <= 8 milliseconds
91.59% <= 9 milliseconds
98.70% <= 10 milliseconds
99.21% <= 11 milliseconds
99.47% <= 12 milliseconds
99.64% <= 13 milliseconds
99.75% <= 14 milliseconds
99.83% <= 15 milliseconds
99.88% <= 16 milliseconds
99.92% <= 17 milliseconds
99.95% <= 18 milliseconds
99.97% <= 19 milliseconds
99.98% <= 20 milliseconds
99.99% <= 21 milliseconds
99.99% <= 22 milliseconds
99.99% <= 23 milliseconds
100.00% <= 24 milliseconds
100.00% <= 25 milliseconds
100.00% <= 26 milliseconds
100.00% <= 26 milliseconds
8844.71 requests per second
====== LRANGE_500 (first 450 elements) ======
1000000 requests completed in 129.66 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.07% <= 2 milliseconds
1.25% <= 3 milliseconds
14.79% <= 4 milliseconds
44.67% <= 5 milliseconds
53.77% <= 6 milliseconds
57.72% <= 7 milliseconds
61.30% <= 8 milliseconds
66.14% <= 9 milliseconds
75.45% <= 10 milliseconds
84.69% <= 11 milliseconds
93.34% <= 12 milliseconds
98.92% <= 13 milliseconds
99.41% <= 14 milliseconds
99.66% <= 15 milliseconds
99.76% <= 16 milliseconds
99.83% <= 17 milliseconds
99.88% <= 18 milliseconds
99.91% <= 19 milliseconds
99.93% <= 20 milliseconds
99.94% <= 21 milliseconds
99.96% <= 22 milliseconds
99.97% <= 23 milliseconds
99.97% <= 24 milliseconds
99.98% <= 25 milliseconds
99.98% <= 26 milliseconds
99.99% <= 27 milliseconds
99.99% <= 28 milliseconds
99.99% <= 29 milliseconds
100.00% <= 30 milliseconds
100.00% <= 31 milliseconds
100.00% <= 32 milliseconds
100.00% <= 32 milliseconds
7712.30 requests per second
====== LRANGE_600 (first 600 elements) ======
1000000 requests completed in 143.27 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.00% <= 1 milliseconds
0.00% <= 2 milliseconds
0.16% <= 3 milliseconds
1.30% <= 4 milliseconds
20.72% <= 5 milliseconds
57.26% <= 6 milliseconds
71.68% <= 7 milliseconds
74.64% <= 8 milliseconds
75.67% <= 9 milliseconds
76.44% <= 10 milliseconds
77.59% <= 11 milliseconds
81.43% <= 12 milliseconds
86.81% <= 13 milliseconds
92.33% <= 14 milliseconds
97.13% <= 15 milliseconds
99.64% <= 16 milliseconds
99.81% <= 17 milliseconds
99.88% <= 18 milliseconds
99.92% <= 19 milliseconds
99.94% <= 20 milliseconds
99.95% <= 21 milliseconds
99.96% <= 22 milliseconds
99.97% <= 23 milliseconds
99.97% <= 24 milliseconds
99.98% <= 25 milliseconds
99.98% <= 26 milliseconds
99.98% <= 27 milliseconds
99.99% <= 28 milliseconds
99.99% <= 29 milliseconds
99.99% <= 30 milliseconds
100.00% <= 31 milliseconds
100.00% <= 32 milliseconds
100.00% <= 33 milliseconds
100.00% <= 34 milliseconds
100.00% <= 35 milliseconds
100.00% <= 35 milliseconds
6980.02 requests per second
====== MSET (10 keys) ======
1000000 requests completed in 41.78 seconds
100 parallel clients
3 bytes payload
keep alive: 1
0.12% <= 1 milliseconds
16.01% <= 2 milliseconds
42.41% <= 3 milliseconds
67.73% <= 4 milliseconds
85.72% <= 5 milliseconds
94.04% <= 6 milliseconds
97.81% <= 7 milliseconds
99.11% <= 8 milliseconds
99.69% <= 9 milliseconds
99.94% <= 10 milliseconds
99.98% <= 11 milliseconds
99.99% <= 12 milliseconds
100.00% <= 13 milliseconds
100.00% <= 14 milliseconds
100.00% <= 15 milliseconds
100.00% <= 16 milliseconds
100.00% <= 17 milliseconds
23934.33 requests per second
- 测试存取大小为100字节的数据包的性能
[root@inspur_1 ~]# redis-benchmark -h 192.168.0.11 -p 7000 -a 888888 -q -d 100
PING_INLINE: 22351.36 requests per second
PING_BULK: 22537.75 requests per second
SET: 22050.72 requests per second
GET: 21729.68 requests per second
INCR: 21925.02 requests per second
LPUSH: 21758.05 requests per second
RPUSH: 21748.59 requests per second
LPOP: 21777.00 requests per second
RPOP: 21677.87 requests per second
SADD: 22002.20 requests per second
HSET: 21838.83 requests per second
SPOP: 22128.79 requests per second
LPUSH (needed to benchmark LRANGE): 21805.50 requests per second
LRANGE_100 (first 100 elements): 11766.09 requests per second
LRANGE_300 (first 300 elements): 8815.23 requests per second
LRANGE_500 (first 450 elements): 7972.57 requests per second
LRANGE_600 (first 600 elements): 7676.95 requests per second
MSET (10 keys): 47258.98 requests per second
慢查询日志
Redis提供了slowlog-log-slower-than和slowlog-max-len配置来收集慢查询的日志。 从字面意思就可以看出, slowlog-log-slower-than就是那个预设阀值,它的单位是微秒(1秒=1000毫秒=1000000微秒) , 默认值是10000, 假如执行了一条“很慢”的命令(例如keys*) , 如果它的执行时间超过了10000微秒, 那么它将被记录在慢查询日志中。
如果slowlog-log-slower-than=0会记录所有的命令, slowlog-log-slowerthan<0对于任何命令都不会进行记录。
为了测试我们把默认值改小一点,
192.168.0.11:7000> config get slowlog-log-slower-than
1) "slowlog-log-slower-than"
2) "20000"
192.168.0.11:7000> config get slowlog-max-len
1) "slowlog-max-len"
2) "128"
192.168.0.11:7000> config set slowlog-log-slower-than 1000
OK
192.168.0.11:7000> rewrite
跑两个测试:
- 只测试某些数值存取的性能
[root@inspur_1 ~]# redis-benchmark -h 192.168.0.11 -p 7000 -a 888888 -n 100000 -q sript load "redis.call('set','foo','bar')"
sript load redis.call('set','foo','bar'): 22306.49 requests per second
[root@inspur_1 ~]# redis-benchmark -h 192.168.0.11 -p 7000 -a 888888 -n 1000000 -q sript load "redis.call('set','foo','bar')"
sript load redis.call('set','foo','bar'): 22374.87 requests per second
[root@inspur_1 ~]# redis-benchmark -h 192.168.0.11 -p 7000 -a 888888 -n 1000000 -q sript load "redis.call('get','foo','bar')"
sript load redis.call('get','foo','bar'): 22392.40 requests per second
- 然后跑一个压力测试1000000次查询的命令,
[root@inspur_1 ~]# redis-benchmark -h 192.168.0.11 -p 7000 -a 88888 -t get,lpush -n 10000000 –q
加大压力,多个命令齐发
这时候在redis-cli中可以看到当前的慢查询日志,有10条:
192.168.0.11:7000> slowlog get
1) 1) (integer) 11
2) (integer) 1585301632
3) (integer) 1151
4) 1) "GET"
2) "key:000000967143"
5) "192.168.0.11:30106"
6) ""
2) 1) (integer) 10
2) (integer) 1585301632
3) (integer) 4382
4) 1) "GET"
2) "key:000000341991"
5) "192.168.0.11:28210"
6) ""
3) 1) (integer) 9
2) (integer) 1585301616
3) (integer) 1473
4) 1) "GET"
2) "key:000000053150"
5) "192.168.0.11:35890"
6) ""
4) 1) (integer) 8
2) (integer) 1585301593
3) (integer) 1581
4) 1) "SET"
2) "key:000000034348"
3) "xxx"
5) "192.168.0.11:4118"
6) ""
5) 1) (integer) 7
2) (integer) 1585301592
3) (integer) 1808
4) 1) "SET"
2) "key:000000116904"
3) "xxx"
5) "192.168.0.11:19288"
6) ""
6) 1) (integer) 6
2) (integer) 1585301587
3) (integer) 2169
4) 1) "SET"
2) "key:000000199775"
3) "xxx"
5) "192.168.0.11:12526"
6) ""
7) 1) (integer) 5
2) (integer) 1585301257
3) (integer) 1398
4) 1) "SET"
2) "key:000000227455"
3) "xxx"
5) "192.168.0.11:40596"
6) ""
8) 1) (integer) 4
2) (integer) 1585296174
3) (integer) 1746
4) 1) "LPUSH"
2) "mylist"
3) "xxx"
5) "192.168.0.11:15868"
6) ""
9) 1) (integer) 3
2) (integer) 1585296112
3) (integer) 1469
4) 1) "LPUSH"
2) "mylist"
3) "xxx"
5) "192.168.0.11:15818"
6) ""
10) 1) (integer) 2
2) (integer) 1585295930
3) (integer) 2404
4) 1) "LPUSH"
2) "mylist"
3) "xxx"
5) "192.168.0.11:15852"
6) ""
解释慢日志的结构:
可以看到每个慢查询日志有4个属性组成, 分别是慢查询日志的标识id、 发生时间戳、 命令耗时、 执行命令和参数。
最佳实践
慢查询功能可以有效地帮助我们找到Redis可能存在的瓶颈, 但在实际使用过程中要注意以下几点:
·slowlog-max-len配置建议: 线上建议调大慢查询列表, 记录慢查询时Redis会对长命令做截断操作, 并不会占用大量内存。 增大慢查询列表可以减缓慢查询被剔除的可能, 例如线上可设置为1000以上。
·slowlog-log-slower-than配置建议: 默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。 由于Redis采用单线程响应命令, 对于高流量的场景, 如果命令执行时间在1毫秒以上, 那么Redis最多可支撑OPS不到1000。 因此对于高OPS场景的Redis建议设置为1毫秒。
·慢查询只记录命令执行时间, 并不包括命令排队和网络传输时间。 因此客户端执行命令的时间会大于命令实际执行时间。 因为命令执行排队机制, 慢查询会导致其他命令级联阻塞, 因此当客户端出现请求超时, 需要检查该时间点是否有对应的慢查询, 从而分析出是否为慢查询导致的命令级联阻塞。
·由于慢查询日志是一个先进先出的队列, 也就是说如果慢查询比较多的情况下, 可能会丢失部分慢查询命令, 为了防止这种情况发生, 可以定期执行slow get命令将慢查询日志持久化到其他存储中(例如MySQL)