文档:基准测试工具

用法

valkey-benchmark [ 选项 ] [--] [ 命令 参数... ]

描述

模拟使用多个客户端发送命令。该工具提供了一组默认测试。您可以使用 -t 选项运行部分测试,或在命令行中提供一个或多个自定义命令。

要在命令行中提供多个命令,请使用 ; 分隔它们,例如 SET foo bar ';' GET foo。(引用 ';' 以防止其被 shell 扩展。)您可以在序列中的命令前加上数字 N,以重复该命令 N 次。在命令参数中,以下占位符会被替换:

__rand_int__ :替换为使用 -r 选项选择范围内的零填充随机整数。

__data__ :替换为由 -d 选项指定大小的数据。

{tag} :替换为将命令路由到正确集群节点的标签。在集群模式下运行时,请将其包含在键名中。

选项

-h 主机名 :服务器主机名 (默认 127.0.0.1)

-p 端口 :服务器端口 (默认 6379)

-s 套接字 :服务器套接字 (覆盖主机和端口设置)

-a 密码 :Valkey 认证密码

--user 用户名 :用于发送 ACL 风格的 'AUTH username pass' 命令。需要 -a 选项。

-u URI :服务器 URI 格式为 valkey://user:password@host:port/dbnum。用户名、密码和数据库编号是可选的。如果没有用户名进行认证,请使用用户名 'default'。对于 TLS,请使用 'valkeys' 方案。

-c 客户端数 :并行连接数 (默认 50)。注意:如果使用 --cluster 选项,则客户端数量必须等于或高于节点数量。

-n 请求数 :总请求数 (默认 100000)

-d 大小 :SET/GET 值的字节数据大小 (默认 3)

--dbnum 数据库 :选择指定的数据库编号 (默认 0)

-3 :以 RESP3 协议模式启动会话。

--threads 数量 :启用多线程模式。

--cluster :启用集群模式。如果在集群模式下通过命令行提供命令,键必须包含 "{tag}"。否则,命令将不会发送到正确的集群节点。

--rfr 模式 :在集群模式下启用从副本读取。此命令必须与 --cluster 选项一起使用。从副本读取有三种模式:

no - 仅向主节点发送读取请求(默认)。

yes - 仅向副本节点发送读取请求。

all - 向所有节点发送读取请求。

由于副本会拒绝写入命令,因此建议仅在读取命令测试中启用从副本读取。

--enable-tracking :在开始基准测试前发送 CLIENT TRACKING ON。

-k 布尔值 :1=保持连接 0=重新连接 (默认 1)

-r 键空间长度 :对 SET/GET/INCR 使用随机键,对 SADD 使用随机值,对 ZADD 使用随机成员和分数。使用此选项,基准测试会将参数中的字符串 __rand_int__ 扩展为一个 12 位数字,范围从 0 到 keyspacelen - 1。每次执行命令时,替换都会改变。默认测试使用此选项来命中指定范围内的随机键。注意:如果省略 -r,则基准测试中的所有命令都将使用相同的键。

-P 请求数 :管道化 请求数 个请求。默认 1 (不使用管道)。

-q :静默模式。只显示每秒查询数。

--precision :延迟输出中显示的小数位数 (默认 0)

--csv :以 CSV 格式输出

-l :循环。永久运行测试。

-t 测试 :只运行逗号分隔的测试列表。测试名称与输出中的名称相同。如果在命令行中提供了特定命令,则 -t 选项将被忽略。

-I :空闲模式。只打开 N 个空闲连接并等待。

-x :从 STDIN 读取最后一个参数。

--seed 数字 :设置随机数生成器的种子。默认种子基于时间。

--tls :建立安全的 TLS 连接。

--sni 主机 :TLS 的服务器名称指示。

--cacert 文件 :用于验证的 CA 证书文件。

--cacertdir 目录 :存储受信任 CA 证书的目录。如果未指定 cacert 和 cacertdir,将应用系统默认的受信任根证书配置。

--insecure :通过跳过证书验证来允许不安全的 TLS 连接。

--cert 文件 :用于认证的客户端证书。

--key 文件 :用于认证的私钥文件。

--tls-ciphers 列表 :设置首选密码套件列表(TLSv1.2 及以下版本),按优先级从高到低排列,以冒号 (":") 分隔。有关此字符串语法的更多信息,请参阅 ciphers(1ssl) 手册页。

--tls-ciphersuites 列表 :设置首选密码套件列表(TLSv1.3),按优先级从高到低排列,以冒号 (":") 分隔。有关此字符串语法的更多信息,特别是 TLSv1.3 密码套件,请参阅 ciphers(1ssl) 手册页。

--rdma :建立 RDMA 连接。

--mptcp :建立 MPTCP 连接。

--help :输出帮助信息并退出。

--version :输出版本信息并退出。

示例

使用默认配置针对 127.0.0.1:6379 运行基准测试。在启动基准测试之前,您需要有一个正在运行的 Valkey 实例。

$ valkey-benchmark

使用 20 个并行客户端运行基准测试,每次管道化 10 个命令,使用 2 个线程,并以更简洁的输出模式运行。

$ valkey-benchmark -c 20 -P 10 --threads 2 -q

使用 20 个并行客户端,总共 10 万个请求,针对 192.168.1.1。

$ valkey-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20

仅使用 SET 测试向 127.0.0.1:6379 填充约 100 万个键。

$ valkey-benchmark -t set -n 1000000 -r 100000000

对 127.0.0.1:6379 的几个命令进行基准测试,并生成 CSV 输出。

$ valkey-benchmark -t ping,set,get -n 100000 --csv

对特定命令行进行基准测试

$ valkey-benchmark -r 10000 -n 10000 eval 'return redis.call("ping")' 0

用 10000 个随机元素填充列表

$ valkey-benchmark -r 10000 -n 10000 lpush mylist __rand_int__

对特定事务进行基准测试

$ valkey-benchmark -- multi ';' set key:__rand_int__ __data__ ';' \
                      incr counter ';' exec\n\n");

只运行部分测试

您无需每次执行 valkey-benchmark 时都运行所有默认测试。例如,要只选择部分测试,请使用 -t 选项,如下例所示:

$ valkey-benchmark -t set,lpush -n 100000 -q
SET: 74239.05 requests per second
LPUSH: 79239.30 requests per second

此示例运行 SETLPUSH 命令的测试,并使用静默模式(参见 -q 开关)。

您甚至可以对特定命令进行基准测试

$ valkey-benchmark -n 100000 -q script load "server.call('set','foo','bar')"
script load server.call('set','foo','bar'): 69881.20 requests per second

选择键空间大小

默认情况下,基准测试针对单个键运行。在 Valkey 中,由于它是一个内存系统,这种合成基准测试与实际测试之间的差异并不大,但是通过使用大键空间,可以强调缓存未命中,并通常模拟更真实的实际工作负载。

这可以通过使用 -r 开关来实现。例如,如果我想运行一百万次 SET 操作,并且每次操作都从 10 万个可能的键中随机选择一个键,我将使用以下命令行:

$ valkey-cli flushall
OK

$ valkey-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

$ valkey-cli dbsize
(integer) 99993

使用管道化

默认情况下,每个客户端(如果未使用 -c 指定,基准测试模拟 50 个客户端)只有在收到上一个命令的回复后才发送下一个命令,这意味着服务器可能需要进行读取调用才能从每个客户端读取每个命令。往返时间 (RTT) 也会产生开销。

Valkey 支持管道化,因此可以一次发送多个命令,这是实际应用中经常利用的一个特性。Valkey 管道化能够显著提高服务器每秒处理操作的数量。

考虑以下使用 16 个命令的管道化运行基准测试的示例:

$ valkey-benchmark -n 1000000 -t set,get -P 16 -q
SET: 403063.28 requests per second
GET: 508388.41 requests per second

使用管道化会显著提高性能。

注意事项

常见陷阱和误解

第一点很明显:有效基准测试的黄金法则是只比较“同类事物”。您可以在相同工作负载下比较不同版本的 Valkey,或者比较相同版本 Valkey 但使用不同选项的性能。如果您计划将 Valkey 与其他系统进行比较,那么评估其功能和技术差异并加以考虑非常重要。

  • Valkey 是一个服务器:所有命令都涉及网络或 IPC 往返。将其与嵌入式数据存储进行比较是毫无意义的,因为大多数操作的成本主要在于网络/协议管理。
  • Valkey 命令对所有常规命令都返回确认。其他一些数据存储则不返回。将 Valkey 与涉及单向查询的数据存储进行比较的用处不大。
  • 天真地重复执行同步 Valkey 命令并不能真正衡量 Valkey 本身,而是测量您的网络(或 IPC)延迟以及客户端库的固有延迟。要真正测试 Valkey,您需要多个连接(如 valkey-benchmark)和/或使用管道化来聚合多个命令,和/或使用多个线程或进程。
  • Valkey 是一个内存数据存储,带有一些可选的持久化选项。如果您计划将其与事务型服务器(如 MySQL、PostgreSQL 等)进行比较,那么您应该考虑启用 AOF 并确定合适的 fsync 策略。
  • 从命令执行的角度来看,Valkey 主要作为单线程服务器运行。尽管服务器可以利用线程进行 I/O 操作和命令解析,但核心命令执行仍然是顺序的。对于需要多核的 CPU 密集型工作负载,用户应考虑并行运行多个 Valkey 实例。将单个 Valkey 实例与多线程数据存储进行比较并不完全公平。

valkey-benchmark 程序是获取数据并评估 Valkey 实例在给定硬件上性能的快速有效方法。然而,默认情况下,它并不代表 Valkey 实例能够维持的最大吞吐量。实际上,通过使用管道化和快速客户端 (libvalkey),编写一个产生比 valkey-benchmark 更高吞吐量的程序是相当容易的。valkey-benchmark 的默认行为是通过利用并发性(即,它创建多个到服务器的连接)来达到吞吐量。如果没有通过 -P 参数显式启用,它根本不使用管道化或任何并行性(每个连接最多一个挂起查询,且无多线程)。因此,在某种程度上,使用 valkey-benchmark 并同时在后台触发例如 BGSAVE 操作,将为用户提供更接近最坏情况而非最佳情况的数字。

要以管道化模式运行基准测试(并实现更高吞吐量),您需要显式使用 -P 选项。请注意,这仍然是一种现实的行为,因为许多基于 Valkey 的应用程序都积极使用管道化来提高性能。但是,您应该使用与您应用程序中能够使用的平均管道长度大致相同的管道大小,以获得更真实的数据。

基准测试应在您想要比较的多个数据存储上应用相同的操作,并以相同的方式工作。将 valkey-benchmark 的结果与另一个基准测试程序的结果进行比较并进行推断是毫无意义的。

例如,可以在单线程模式下比较 Valkey 和 memcached 在 GET/SET 操作上的性能。它们都是内存数据存储,在协议层面工作方式大致相同。只要它们各自的基准测试应用程序以相同方式(管道化)聚合查询并使用相似数量的连接,这种比较实际上是有意义的。

当您对 Valkey 这样的高性能内存数据库进行基准测试时,可能很难使服务器达到饱和状态。有时,性能瓶颈在客户端,而不是服务器端。在这种情况下,必须修复或扩展客户端(即基准测试程序本身),以达到最大吞吐量。

影响 Valkey 性能的因素

有多种因素直接影响 Valkey 的性能。我们在此提及它们,因为它们会改变任何基准测试的结果。然而请注意,在低端、未经调优的机器上运行的典型 Valkey 实例通常能为大多数应用程序提供足够好的性能。

  • 网络带宽和延迟通常直接影响性能。在启动基准测试之前,使用 ping 程序快速检查客户端和服务器主机之间的延迟是否正常是一个好习惯。关于带宽,通常有必要估算以 Gbit/s 为单位的吞吐量,并将其与网络的理论带宽进行比较。例如,一个在 Valkey 中以 100000 q/s 写入 4 KB 字符串的基准测试,实际上会消耗 3.2 Gbit/s 的带宽,可能适用于 10 Gbit/s 的链路,但不适用于 1 Gbit/s 的链路。在许多实际场景中,Valkey 的吞吐量受限于网络,远早于受限于 CPU。为了在单个服务器上整合多个高吞吐量的 Valkey 实例,值得考虑安装 10 Gbit/s 网卡或多个 1 Gbit/s 网卡并进行 TCP/IP 绑定。

  • CPU 是另一个重要因素。

  • RAM 速度和内存带宽对于整体性能似乎不那么关键,特别是对于小对象。然而,对于大对象(>10 KB),它可能会变得显而易见。通常,购买昂贵的快速内存模块来优化 Valkey 并不划算。

  • 与使用相同硬件但在非虚拟化环境下运行相比,Valkey 在虚拟机 (VM) 上运行速度较慢。如果您有机会在物理机上运行 Valkey,这是首选。然而,这并不意味着 Valkey 在虚拟化环境中很慢,其提供的性能仍然非常好,并且您在虚拟化环境中可能遇到的严重性能问题大多是由于过度配置、高延迟的非本地磁盘,或具有缓慢 fork 系统调用实现的旧版管理程序软件造成的。

  • 当服务器和客户端基准测试程序在同一台机器上运行时,可以使用 TCP/IP 回环接口和 Unix 域套接字。根据平台的不同,Unix 域套接字可以比 TCP/IP 回环接口实现约 50% 的更高吞吐量(例如在 Linux 上)。valkey-benchmark 的默认行为是使用 TCP/IP 回环接口。

  • 当大量使用管道化(即长管道)时,Unix 域套接字相对于 TCP/IP 回环接口的性能优势会趋于减小。

  • 当使用以太网访问 Valkey 时,如果数据大小保持在以太网数据包大小(约 1500 字节)以下,使用管道化聚合命令会特别高效。实际上,处理 10 字节、100 字节或 1000 字节的查询几乎会产生相同的吞吐量。参见下图。

    Data size impact

  • 在多 CPU 插槽服务器上,Valkey 的性能取决于 NUMA 配置和进程位置。最明显的效果是 valkey-benchmark 结果似乎是非确定性的,因为客户端和服务器进程随机分布在核心上。为了获得确定性结果,需要使用进程放置工具(在 Linux 上:taskset 或 numactl)。最有效的组合始终是将客户端和服务器放在同一 CPU 的两个不同核心上,以利用 L3 缓存。以下是针对 3 种服务器 CPU(AMD Istanbul、Intel Nehalem EX 和 Intel Westmere)在不同相对位置下进行 4 KB SET 基准测试的一些结果。请注意,此基准测试并非旨在比较 CPU 型号本身(因此未披露 CPU 的确切型号和频率)。

    NUMA chart

  • 在高端配置下,客户端连接数也是一个重要因素。基于 epoll/kqueue,Valkey 事件循环具有很强的可伸缩性。Valkey 已在超过 60000 个连接下进行过基准测试,并在此条件下仍能保持 50000 q/s 的吞吐量。根据经验法则,拥有 30000 个连接的实例只能处理 100 个连接时可达吞吐量的一半。以下是显示 Valkey 实例每连接数吞吐量的示例:

    connections chart

  • 在高端配置下,通过调整网卡 (NIC) 配置和相关中断,可以实现更高的吞吐量。最佳吞吐量是通过设置 Rx/Tx 网卡队列与 CPU 核心之间的亲和性,并激活 RPS (Receive Packet Steering) 支持来实现的。更多信息请参阅此帖子。使用巨型帧 (Jumbo frames) 也可能在使用大对象时提供性能提升。

  • 根据平台的不同,Valkey 可以针对不同的内存分配器(libc malloc, jemalloc, tcmalloc)进行编译,这些分配器在原始速度、内部和外部碎片方面可能具有不同的行为。如果您没有自己编译 Valkey,可以使用 INFO 命令检查 mem_allocator 字段。请注意,大多数基准测试运行时间不足以产生显著的外部碎片(与生产 Valkey 实例不同)。

其他考量因素

任何基准测试的一个重要目标是获得可重现的结果,以便与其他测试结果进行比较。

  • 一个好的做法是尽可能在隔离的硬件上运行测试。如果不可能,则必须监控系统以检查基准测试是否受到某些外部活动的影响。
  • 某些配置(桌面电脑和笔记本电脑肯定如此,一些服务器也一样)具有可变的 CPU 核心频率机制。控制此机制的策略可以在操作系统级别设置。某些 CPU 型号在根据工作负载调整 CPU 核心频率方面比其他型号更激进。为了获得可重现的结果,最好为所有参与基准测试的 CPU 核心设置尽可能高的固定频率。
  • 一个重要点是根据基准测试调整系统大小。系统必须有足够的 RAM 且不能发生交换。在 Linux 上,不要忘记正确设置 overcommit_memory 参数。请注意,32 位和 64 位 Valkey 实例的内存占用不同。
  • 如果您计划在基准测试中使用 RDB 或 AOF,请检查系统中没有其他 I/O 活动。避免将 RDB 或 AOF 文件放在 NAS 或 NFS 共享上,或任何其他影响您网络带宽和/或延迟的设备上(例如,Amazon EC2 上的 EBS)。
  • 将 Valkey 的日志级别(loglevel 参数)设置为 warning 或 notice。避免将生成的日志文件放在远程文件系统上。
  • 避免使用可能改变基准测试结果的监控工具。例如,定期使用 INFO 命令收集统计信息可能没问题,但 MONITOR 会显著影响测量的性能。
  • 当在与被测试的 valkey-server 相同的机器上运行 valkey-benchmark 时,您可能需要至少使用两个线程(--threads 2)来运行基准测试,以防止基准测试工具本身成为瓶颈,即防止 valkey-benchmark 占用 100% 的 CPU 而 valkey-server 使用不到 100% 的 CPU。

其他 Valkey 基准测试工具

有几个第三方工具可用于 Valkey 的基准测试。有关其目标和功能的更多信息,请查阅每个工具的文档。

  • 来自 Redis Ltd.memtier_benchmark 是一款 NoSQL Valkey、Redis 和 Memcache 流量生成与基准测试工具。
  • 来自 Twitterrpc-perf 是一款用于对支持 Valkey 和 Memcache 的 RPC 服务进行基准测试的工具。
  • 来自 Yahoo @YahooYCSB 是一个基准测试框架,支持包括 Valkey 在内的多种数据库客户端。

另请参阅

valkey-cli, valkey-server