Redis 基准测试
在 Redis 服务器上使用 redis-benchmark 实用程序
Redis 堆栈 | Redis 社区版 |
---|
Redis 有多快?
Redis 包括redis-benchmark
模拟正在运行的命令完成的实用程序
由 N 个客户端同时发送 M 个查询(类似于
Apache 的ab
实用程序)。您将在下面找到执行的基准测试的完整输出
针对 Linux 机器。
支持以下选项:
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
--user <username> Used to send ACL style 'AUTH username pass'. Needs -a.
-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 3)
--dbnum <db> SELECT the specified db number (default 0)
--threads <num> Enable multi-thread mode.
--cluster Enable cluster mode.
--enable-tracking Send CLIENT TRACKING on before starting benchmark.
-k <boolean> 1=keep alive 0=reconnect (default 1)
-r <keyspacelen> Use random keys for SET/GET/INCR, random values for
SADD, random members and scores for ZADD.
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).
-e If server replies with errors, show them on stdout.
(No more than 1 error per second is displayed.)
-q Quiet. Just show query/sec values
--precision Number of decimal places to display in latency output (default 0)
--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.
-I Idle mode. Just open N idle connections and wait.
--help Output this help and exit.
--version Output version and exit.
在启动基准测试之前,您需要有一个正在运行的 Redis 实例。 一个典型的例子是:
redis-benchmark -q -n 100000
使用这个工具非常简单,你也可以编写自己的基准测试, 但与任何基准测试活动一样,也有一些陷阱需要避免。
仅运行测试的子集
您无需在每次执行 redis-benchmark 时都运行所有默认测试。
仅选择测试子集的最简单方法是使用-t
选择
如以下示例所示:
$ redis-benchmark -t set,lpush -n 100000 -q
SET: 180180.17 requests per second, p50=0.143 msec
LPUSH: 188323.91 requests per second, p50=0.135 msec
在上面的示例中,我们要求只运行 test SET 和 LPUSH 命令,
在安静模式下(请参阅-q
switch) 的
也可以直接指定要进行基准测试的命令,就像在 以下示例:
$ 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
开关。例如,如果我想运行
100 万次 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
使用 pipelining
默认情况下,每个客户端(基准测试模拟 50 个客户端,否则
指定-c
) 仅在上一个
命令,这意味着服务器可能需要读取调用
以便从每个客户端读取每个命令。此外,RTT 也需要付费。
Redis 支持流水线,因此可以发送 一次执行多个命令,这是实际应用程序经常利用的功能。 Redis 流水线能够显著提高每个 其次,服务器能够交付。
这是在 MacBook Air 11 英寸中运行基准测试的示例,使用 16 个命令的流水线:
$ redis-benchmark -n 1000000 -t set,get -P 16 -q
SET: 1536098.25 requests per second, p50=0.479 msec
GET: 1811594.25 requests per second, p50=0.391 msec
使用 pipelining 可以显著提高性能。
陷阱和误解
第一点很明显:一个有用的基准测试的黄金法则是 只比较 apples 和 apples。可以比较不同版本的 Redis 例如,在相同的工作负载上。或者是相同版本的 Redis,但带有 不同的选项。如果您打算将 Redis 与其他产品进行比较,那么它是 评估功能和技术差异并采取重要措施 在账户中。
- Redis 是一个服务器,因此所有命令都涉及网络往返。嵌入式数据存储不涉及网络和协议管理。将此类产品与 Redis 进行比较时,应使用命令执行时间,而不是端到端时间。
- Redis 命令返回所有常用命令的确认。其他一些数据存储则不需要。将 Redis 与涉及单向查询的存储进行比较,其用处不大。
- 天真地迭代同步 Redis 命令并不会对 Redis 本身进行基准测试,而是测量您的网络(或 IPC)延迟和客户端库固有延迟。要真正测试 Redis,您需要多个连接(如 redis-benchmark)和/或使用 pipelining 聚合多个命令和/或多个线程或进程。
- Redis 是一种内存数据存储,具有一些可选的持久性选项。如果您打算将其与事务服务器(MySQL、PostgreSQL 等)进行比较,那么您应该考虑激活 AOF 并选择合适的 fsync 策略。
- 从命令执行的角度来看,Redis 主要是单线程服务器(实际上现代版本的 Redis 使用线程来处理不同的事情)。它不是为了从多个 CPU 内核中受益而设计的。如果需要,人们应该启动多个 Redis 实例,以便在多个内核上横向扩展。将单个 Redis 实例与多线程数据存储进行比较并不公平。
一个常见的误解是 redis-benchmark 旨在使 Redis 性能看起来非常出色,redis-benchmark 实现的吞吐量是 有点人为的,并且无法通过实际应用程序来实现。这是 其实不是真的。
这redis-benchmark
程序是获取一些数字和
评估 Redis 实例在给定硬件上的性能。然而
默认情况下,它不表示 Redis 实例可以的最大吞吐量
维持。实际上,通过使用 pipelining 和快速客户端 (hiredis),它是相当的
易于编写程序,产生比 redis-benchmark 更高的吞吐量。这
redis-benchmark 的默认行为是通过利用
仅并发(即它创建多个与服务器的连接)。
它根本不使用流水线或任何并行性(每个
连接,并且没有多线程),如果未通过
这-P
参数。因此,在某种程度上使用redis-benchmark
并且,触发,用于
example,一个BGSAVE
同时在后台作,将提供
数字更接近最坏情况而不是最佳情况的用户。
要使用 pipelining 模式运行基准测试(并实现更高的吞吐量), 您需要显式使用 -P 选项。请注意,它仍然是一个 真实行为,因为许多基于 Redis 的应用程序积极使用 流水线以提高性能。但是,您应该使用满足以下条件的管道大小 或多或少是您可以在 应用程序以获得真实的数字。
最后,基准测试应应用相同的作,并以相同的方式工作 替换为要比较的多个数据存储。这绝对没有意义 将 redis-benchmark 的结果与另一个 benchmark 的结果进行比较 程序和外推。
例如,可以在 GET/SET作。两者都是内存中的数据存储,主要在同一环境中工作 方式。前提是他们各自的基准测试应用程序是 以相同的方式聚合查询 (pipelining) 并使用相似数量的 connections,这个比较其实是有意义的。
Redis (antirez) 和 Memcached (Dormando) 开发人员。
antirez 1 - 在 Redis、Memcached、Speed、Benchmarks 和 The Toilet 上
dormando - Redis VS Memcached(板凳稍好)
antirez 2 - Memcached/Redis 基准测试的更新
您可以看到,最终,两个解决方案之间的区别不是 一旦考虑到所有技术方面,就太令人震惊了。请注意两者 在这些基准测试之后,Redis 和 memcached 得到了进一步的优化。
最后,当对非常高效的服务器进行基准测试(并且像 Redis 这样的 store 或者 memcached 肯定属于这一类),它可能很难饱和 服务器。有时,性能瓶颈在客户端, 而不是服务器端。在这种情况下,客户端(即基准测试程序本身) 必须固定或横向扩展,才能达到最大吞吐量。
影响 Redis 性能的因素
有多种因素对 Redis 性能有直接影响。 我们在这里提到它们,因为它们可以改变任何基准测试的结果。 但请注意,在低端 untuned box 通常为大多数应用程序提供足够好的性能。
- 网络带宽和延迟通常对性能有直接影响。 使用 ping 程序快速检查延迟是一个不错的做法 在启动 benchmark 之前,客户端和 server 主机之间是正常的。 关于带宽,估计通常是有用的 吞吐量(以 Gbit/s 为单位),并将其与理论带宽进行比较 的网络。例如,基准测试设置 4 KB 字符串 在 Redis 中,以 100000 q/s 的速度,实际会消耗 3.2 Gbit/s 的带宽 并且可能适合 10 Gbit/s 链路,但不适合 1 Gbit/s 链路。在许多真实 世界场景,Redis 吞吐量在之前就受到网络的限制 受 CPU 限制。整合多个高吞吐量 Redis 实例 在单个服务器上,值得考虑放置一个 10 Gbit/s 的 NIC 或多个具有 TCP/IP 绑定的 1 Gbit/s 网卡。
- CPU 是另一个非常重要的因素。作为单线程,Redis 偏爱 具有大缓存且内核不多的快速 CPU。在这个游戏中,Intel CPU 是 目前是赢家。只有一半的性能并不少见 AMD Opteron CPU 与类似的 Nehalem EP/Westmere EP/Sandy Bridge 的比较 带有 Redis 的 Intel CPU。当客户端和服务器在同一个盒子上运行时,CPU 为 redis-benchmark 的限制因素。
- RAM 速度和内存带宽似乎对整体性能不太重要 特别是对于小物体。对于大型对象 (>10 KB),它可能会变为 不过很明显。通常,买贵的钱并不划算 快速内存模块以优化 Redis。
- 与不使用虚拟化的情况下运行相比,Redis 在 VM 上的运行速度更慢
相同的硬件。如果您有机会在物理机器上运行 Redis
这是首选。然而,这并不意味着 Redis 在
虚拟化环境,交付的性能仍然非常好
以及您在 virtualized 中可能遇到的大多数严重性能问题
环境是由于过度预置、具有高延迟的非本地磁盘、
或运行缓慢的旧虚拟机管理程序软件
fork
syscall 实现。 - 当服务器和客户端基准测试程序在同一个 Box 上运行时,两者 可以使用 TCP/IP loopback 和 unix 域套接字。根据 平台,UNIX 域套接字的吞吐量比 TCP/IP 环回(例如在 Linux 上)。默认行为 redis-benchmark 使用 TCP/IP 环回。
- 与 TCP/IP 环回相比,unix 域套接字的性能优势 当大量使用流水线(即长管道)时,往往会减少。
- 当使用以太网访问 Redis 时,使用 当数据大小保持在 以太网数据包大小(约 1500 字节)。实际上,处理 10 个字节, 100 字节或 1000 字节的查询几乎会导致相同的吞吐量。 见下图。
- 在多 CPU 套接字服务器上,Redis 性能取决于 NUMA 配置和进程位置。最明显的效果是 redis-benchmark 结果似乎不确定,因为 client 和 server 进程在内核上随机分布。为了获得确定性结果, 需要使用进程放置工具(在 Linux 上:taskset 或 numactl)。 最有效的组合总是将客户端和服务器放在两个 同一 CPU 的不同内核从 L3 缓存中受益。 以下是 3 个服务器 CPU(AMD Istanbul、 Intel Nehalem EX 和 Intel Westmere),具有不同的相对位置。 请注意,此基准测试并非用于比较 CPU 型号 (因此,CPU 的确切型号和频率未披露)。
- 对于高端配置,客户端连接数也是 重要因素。基于 epoll/kqueue,Redis 事件循环相当 可 伸缩。Redis 已经在超过 60000 个连接上进行了基准测试, 并且仍然能够在这些条件下维持 50000 Q/s。根据经验, 具有 30000 个连接的实例只能处理一半的吞吐量 可通过 100 个连接实现。以下示例显示了 每个连接数一个 Redis 实例:
- 使用高端配置,可以通过以下方式实现更高的吞吐量 调整 NIC 配置和关联的中断。最佳吞吐量 是通过设置 Rx/Tx NIC 队列和 CPU 内核之间的关联来实现的, 以及激活 RPS (Receive Packet Steering) 支持。更多信息请见此帖子。 使用大型对象时,巨型帧还可以提高性能。
- 根据平台的不同,Redis 可以针对不同的内存进行编译
分配器(libc malloc、jemalloc、tcmalloc),它们可能具有不同的行为
在原始速度、内部和外部碎片方面。
如果你没有自己编译 Redis,可以使用 INFO 命令检查
这
mem_allocator
田。请注意,大多数基准测试的运行时间不够长,无法 生成大量外部碎片(与生产 Redis 相反 实例)。
其他需要考虑的事项
任何基准测试的一个重要目标是获得可重复的结果,因此 可以与其他测试的结果进行比较。
- 一个好的做法是尝试尽可能在隔离的硬件上运行测试。 如果不可能,则必须监控系统以检查基准测试 不受某些外部活动的影响。
- 一些配置(当然是台式机和笔记本电脑,还有一些服务器) 具有可变的 CPU 内核频率机制。控制此 机制。某些 CPU 型号比 其他任务则负责根据工作负载调整 CPU 内核的频率。要获取 结果可重复,最好设置尽可能高的固定频率 对于基准测试中涉及的所有 CPU 内核。
- 重要的一点是要根据基准来调整系统的大小。
系统必须有足够的 RAM,并且不能交换。在 Linux 上,不要忘记
要设置
overcommit_memory
参数。请注意 32 位和 64 位 Redis 实例的内存占用量不同。 - 如果您打算使用 RDB 或 AOF 作为基准测试,请检查没有其他 系统中的 I/O 活动。避免将 RDB 或 AOF 文件放在 NAS 或 NFS 共享上, 或在影响您的网络带宽和/或延迟的任何其他设备上 (例如,Amazon EC2 上的 EBS)。
- 将 Redis 日志记录级别(loglevel 参数)设置为 warning 或 notice。避免将 在远程文件系统上生成的日志文件。
- 避免使用可能会改变基准测试结果的监控工具。为 实例定期使用 INFO 收集统计信息可能没问题, 但 MONITOR 会显著影响测量的性能。
跨不同 Redis 版本的裸机服务器上的基准测试结果
在每个发布的版本上无缝保留或改进 Redis 性能至关重要。
为了评估它,我们在 Redis 的已发布版本(从 v2.6.0 开始)上使用redis-benchmark
在独立 Redis 服务器上的一系列命令类型上,多次重复相同的基准测试,确保其统计显著性,并测量运行间的方差。
使用的硬件平台是稳定的裸机 HPE ProLiant DL380 Gen10 服务器,配备一个英特尔® 至强® Gold 6230 CPU @ 2.10GHz,禁用英特尔超线程技术,禁用 CPU 频率缩放,所有可配置的 BIOS 和 CPU 系统设置都设置为性能。
该盒子运行 Ubuntu 18.04 Linux 版本 4.15.0-123,Redis 使用 gcc 7.5.0 编译。
使用的基准测试客户端 (redis-benchmark
) 在所有测试中保持稳定,并且版本redis-benchmark 6.2.0 (git:445aa844)
.
redis-server 和 redis-benchmark 进程都固定到特定的物理内核。
在测试中使用了以下基准测试选项:
- 测试是在 50 个客户端同时执行 500 万个请求的情况下完成的。
- 使用环回接口执行测试。
- 测试在没有流水线的情况下执行。
- 使用的有效负载大小为 256 字节。
- 对于每个 redis-benchmark 进程,使用了 2 个线程来确保 benchmark 客户端不是瓶颈。
- 对 Strings、Hashes、Sets 和 Sorted Sets 数据类型进行了基准测试。
下面我们介绍按数据类型划分的获得的结果。
其他 Redis 基准测试工具
有几种第三方工具可用于对 Redis 进行基准测试。请参阅每个工具的 文档,了解有关其目标和功能的更多信息。
- Redis Labs 的 memtier_benchmark 是一款 NoSQL Redis 和 Memcache 流量生成和基准测试工具。
- 来自 Twitter 的 rpc-perf 是一个用于对支持 Redis 和 Memcache 的 RPC 服务进行基准测试的工具。
- Yahoo @Yahoo 的 YCSB 是一个基准测试框架,客户端支持许多数据库,包括 Redis。