Linode 2048 instance (with pipelining)本文基于Redis 6.0.9版本,前提至少 Redis 3.0或更高版本。
目录
1.Redis基准测试
1.1.仅运行部分测试
1.2.选择键空间的大小
1.3.使用流水线(pipelining)
1.4.陷阱和误解(Pitfalls and misconceptions)
1.5.影响Redis性能的因素
1.6.其他要考虑的事情
2.在不同的虚拟化服务器和裸机服务器上获得基准测试结果
2.1.没有流水线的更详细的测试
3.其他Redis基准测试工具
4.优化高端服务器硬件的Redis基准测试结果示例
查看Redis在不同平台上的运行速度。
Redis包含redis-benchmark实用程序,该实用程序模拟N个客户端同时发送M个总计查询的正在运行的命令(类似于Apache的ab
实用程序)。 在下面,你将找到针对Linux系统执行的基准测试的完整输出。
支持以下选项:
Usage: redis-benchmark [-h ] [-p ] [-c ] [-n [-k ]
-h Server hostname (default 127.0.0.1)
-p Server port (default 6379)
-s Server socket (overrides host and port)
-a Password for Redis Auth
-c Number of parallel connections (default 50)
-n Total number of requests (default 100000)
-d Data size of SET/GET value in bytes (default 2)
--dbnum SELECT the specified db number (default 0)
-k 1=keep alive 0=reconnect (default 1)
-r 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 Pipeline requests. Default 1 (no pipeline).
-q Quiet. Just show query/sec values
--csv Output in CSV format
-l Loop. Run the tests forever
-t Only run the comma separated list of tests. The test
names are the same as the ones produced as output.
-I Idle mode. Just open N idle connections and wait.
启动基准之前,你需要具有运行中的Redis实例。 一个典型的例子是:
redis-benchmark -q -n 100000
使用此工具非常容易,你也可以编写自己的基准测试,但与任何基准测试活动一样,有一些陷阱要避免。
你无需在每次执行redis-benchmark时都运行所有默认测试。 仅选择测试子集的最简单方法是使用 -t
选项,如以下示例所示:
$ redis-benchmark -t set,lpush -n 100000 -q
SET: 74239.05 requests per second
LPUSH: 79239.30 requests per second
在上面的示例中,我们要求以安静模式运行测试SET和LPUSH命令(请参见 -q
开关)。
也可以像下面的示例一样直接指定要进行基准测试的命令:
$ redis-benchmark -n 100000 -q script load "redis.call('set','foo','bar')"
script load redis.call('set','foo','bar'): 69881.20 requests per second
默认情况下,基准测试针对单个键运行。 在Redis中,这样的综合基准与实际基准之间的差异并不大,因为它是内存系统,但是可以强调缓存未命中,并且通常可以使用大键来模拟更实际的工作负载空间。
这是通过使用 -r
开关获得的。 例如,如果我要运行一百万个SET操作,并对100k个可能的键中的每个操作使用一个随机键,我将使用以下命令行:
$ redis-cli flushall
OK
$ redis-benchmark -t set -r 100000 -n 1000000
====== SET ======
1000000 requests completed in 13.86 seconds
50 parallel clients
3 bytes payload
keep alive: 1
99.76% `<=` 1 milliseconds
99.98% `<=` 2 milliseconds
100.00% `<=` 3 milliseconds
100.00% `<=` 3 milliseconds
72144.87 requests per second
$ redis-cli dbsize
(integer) 99993
默认情况下,每个客户端(基准测试模拟50个客户端,如果未使用 -c
另行指定)仅在收到前一个命令的回复时才发送下一个命令,这意味着服务器可能需要read调用才能读取每个命令来自每个客户。 另外,RTT也要付费。
Redis支持流水线(pipelining),因此可以一次发送多个命令,这是现实世界应用程序经常利用的功能。 Redis流水线能够极大地提高服务器每秒能够执行的操作数量。
这是使用16条命令的流水线,在MacBook Air 11中,运行基准测试的示例:
$ redis-benchmark -n 1000000 -t set,get -P 16 -q
SET: 403063.28 requests per second
GET: 508388.41 requests per second
使用流水线可显着提高性能。
第一点很明显:有用的基准测试的黄金法则是只比较apples 和apples 。 例如,可以在相同的工作负载上比较不同版本的Redis。 或相同版本的Redis,但具有不同的选项。 如果你打算将Redis与其他东西进行比较,那么评估功能和技术差异并加以考虑就很重要。
一个常见的误解是redis-benchmark旨在使Redis的性能看起来很出色,redis-benchmark所实现的吞吐量有些人为,而实际应用无法实现。 这实际上是不正确的。
redis-benchmark程序是获取一些数字并评估给定硬件上Redis实例性能的一种快速而有用的方法。 但是,默认情况下,它不代表Redis实例可以维持的最大吞吐量。 实际上,通过使用流水线和快速客户端(hiredis),编写一个比redis-benchmark产生更多吞吐量的程序相当容易。 redis-benchmark的默认行为是仅通过利用并发来实现吞吐量(即,它创建到服务器的多个连接)。 如果未通过 -P
参数明确启用,则它根本不使用流水线或任何并行性(每个连接最多一个未决查询,并且没有多线程)。 因此,通过某种方式使用redis-benchmark并在后台同时触发例如BGSAVE 操作,将为用户提供比最坏情况更接近最佳情况的数字。
要使用流水线模式运行基准测试(并实现更高的吞吐量),你需要显式使用-P选项。 请注意,由于许多基于Redis的应用程序都在积极使用流水线来提高性能,因此这仍然是现实的行为。 但是,你应该使用的流水线大小应大于或小于你可以在应用程序中使用的平均流水线长度,以便获得实际数字。
最后,基准测试应应用相同的操作,并以相同的方式处理要比较的多个数据存储。 将redis-benchmark的结果与另一个基准程序的结果进行比较并推断是绝对没有意义的。
例如,可以在GET/SET操作上比较单线程模式下的Redis和memcached。 两者都是内存中的数据存储,在协议级别上大多数都以相同的方式工作。 如果它们各自的基准应用程序以相同的方式(流水线)聚合查询并使用相似数量的连接,则该比较实际上是有意义的。
Redis(antirez)和memcached(dormando)开发人员之间的对话框说明了这个完美的示例。
你可以看到,一旦考虑了所有技术方面,两种解决方案之间的差异就不会那么惊人。 请注意,在这些基准测试之后,Redis和memcached均已进行了进一步优化。
最后,当对非常高效的服务器进行基准测试(并且Redis或memcached之类的存储肯定属于此类)时,可能很难使服务器饱和。 有时,性能瓶颈在客户端而不是服务器端。 在那种情况下,客户端(即基准程序本身)必须是固定的,或者可能是横向扩展的,以便达到最大吞吐量。
有多种因素直接影响Redis的性能。 我们在这里提到它们,因为它们可以改变任何基准测试的结果。 但是请注意,在低端,未调整的盒子上运行的典型Redis实例通常为大多数应用程序提供足够好的性能。
任何基准测试的一个重要目标是获得可重复的结果,因此可以将它们与其他测试的结果进行比较。
overcommit_memory
参数。 请注意,32位和64位Redis实例的内存占用不同。警告:请注意,以下大多数基准测试已有几年历史,并且是通过旧硬件与今天的标准进行比较获得的。 该页面应该进行更新,但是在许多情况下,使用硬硬件状态,你可以期望看到的数字是此处看到的数字的两倍。 而且,Redis 4.0在许多工作负载中都比2.6快。
Intel(R) Xeon(R) CPU E5520 @ 2.27GHz (有流水线)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -P 16 -q
SET: 552028.75 requests per second
GET: 707463.75 requests per second
LPUSH: 767459.75 requests per second
LPOP: 770119.38 requests per second
Linode 2048 instance (有流水线)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q -P 16
SET: 195503.42 requests per second
GET: 250187.64 requests per second
LPUSH: 230547.55 requests per second
LPOP: 250815.16 requests per second
Linode 2048 instance (无流水线)
$ ./redis-benchmark -r 1000000 -n 2000000 -t get,set,lpush,lpop -q
SET: 35001.75 requests per second
GET: 37481.26 requests per second
LPUSH: 36968.58 requests per second
LPOP: 35186.49 requests per second
$ redis-benchmark -n 100000
====== SET ======
100007 requests completed in 0.88 seconds
50 parallel clients
3 bytes payload
keep alive: 1
58.50% <= 0 milliseconds
99.17% <= 1 milliseconds
99.58% <= 2 milliseconds
99.85% <= 3 milliseconds
99.90% <= 6 milliseconds
100.00% <= 9 milliseconds
114293.71 requests per second
====== GET ======
100000 requests completed in 1.23 seconds
50 parallel clients
3 bytes payload
keep alive: 1
43.12% <= 0 milliseconds
96.82% <= 1 milliseconds
98.62% <= 2 milliseconds
100.00% <= 3 milliseconds
81234.77 requests per second
====== INCR ======
100018 requests completed in 1.46 seconds
50 parallel clients
3 bytes payload
keep alive: 1
32.32% <= 0 milliseconds
96.67% <= 1 milliseconds
99.14% <= 2 milliseconds
99.83% <= 3 milliseconds
99.88% <= 4 milliseconds
99.89% <= 5 milliseconds
99.96% <= 9 milliseconds
100.00% <= 18 milliseconds
68458.59 requests per second
====== LPUSH ======
100004 requests completed in 1.14 seconds
50 parallel clients
3 bytes payload
keep alive: 1
62.27% <= 0 milliseconds
99.74% <= 1 milliseconds
99.85% <= 2 milliseconds
99.86% <= 3 milliseconds
99.89% <= 5 milliseconds
99.93% <= 7 milliseconds
99.96% <= 9 milliseconds
100.00% <= 22 milliseconds
100.00% <= 208 milliseconds
88109.25 requests per second
====== LPOP ======
100001 requests completed in 1.39 seconds
50 parallel clients
3 bytes payload
keep alive: 1
54.83% <= 0 milliseconds
97.34% <= 1 milliseconds
99.95% <= 2 milliseconds
99.96% <= 3 milliseconds
99.96% <= 4 milliseconds
100.00% <= 9 milliseconds
100.00% <= 208 milliseconds
71994.96 requests per second
注意:将有效负载从256更改为1024或4096字节不会显着改变数字(但是,答复数据包最多粘合到1024字节,因此对于较大的有效负载,GET可能会变慢)。 客户端数量相同,从50到256个客户端,我得到的数量相同。 只有10个客户端,它开始变得有点慢。
你可以从不同的盒子获得不同的结果。 例如,一个运行在Linux 2.6上,频率为1.66 GHz的Intel Core du T5500等低调机箱将输出以下内容:
$ ./redis-benchmark -q -n 100000
SET: 53684.38 requests per second
GET: 45497.73 requests per second
INCR: 39370.47 requests per second
LPUSH: 34803.41 requests per second
LPOP: 37367.20 requests per second
另一个使用64位盒的Xeon L5420时钟频率为2.5 GHz:
$ ./redis-benchmark -q -n 100000
PING: 111731.84 requests per second
SET: 108114.59 requests per second
GET: 98717.67 requests per second
INCR: 95241.91 requests per second
LPUSH: 104712.05 requests per second
LPOP: 93722.59 requests per second
有几种第三方工具可用于对Redis进行基准测试。 有关每个工具的目标和功能的更多信息,请参阅每个工具的文档。
使用Unix域套接字:
$ numactl -C 6 ./redis-benchmark -q -n 100000 -s /tmp/redis.sock -d 256
PING (inline): 200803.22 requests per second
PING: 200803.22 requests per second
MSET (10 keys): 78064.01 requests per second
SET: 198412.69 requests per second
GET: 198019.80 requests per second
INCR: 200400.80 requests per second
LPUSH: 200000.00 requests per second
LPOP: 198019.80 requests per second
SADD: 203665.98 requests per second
SPOP: 200803.22 requests per second
LPUSH (again, in order to bench LRANGE): 200000.00 requests per second
LRANGE (first 100 elements): 42123.00 requests per second
LRANGE (first 300 elements): 15015.02 requests per second
LRANGE (first 450 elements): 10159.50 requests per second
LRANGE (first 600 elements): 7548.31 requests per second
使用TCP回送(loopback):
$ numactl -C 6 ./redis-benchmark -q -n 100000 -d 256
PING (inline): 145137.88 requests per second
PING: 144717.80 requests per second
MSET (10 keys): 65487.89 requests per second
SET: 142653.36 requests per second
GET: 142450.14 requests per second
INCR: 143061.52 requests per second
LPUSH: 144092.22 requests per second
LPOP: 142247.52 requests per second
SADD: 144717.80 requests per second
SPOP: 143678.17 requests per second
LPUSH (again, in order to bench LRANGE): 143061.52 requests per second
LRANGE (first 100 elements): 29577.05 requests per second
LRANGE (first 300 elements): 10431.88 requests per second
LRANGE (first 450 elements): 7010.66 requests per second
LRANGE (first 600 elements): 5296.61 requests per second