这项 Redis 延迟基准测试衡量 HotKV、Redis、Valkey 和 Dragonfly 在固定请求速率下响应需要多长时间。我们之前的基准测试衡量的是吞吐量,有读者正确地指出吞吐量并不是全部。因此我们保持负载恒定,逐级提高,并在每一级记录中位数(p50)和第 99 百分位(p99)。我们还测量了 pub/sub 的投递时间。
简而言之。 在 AWS 上的这项 Redis 延迟基准测试中,HotKV 和 Dragonfly 都能维持每秒 160 万次 GET,8 个 I/O 线程的 Redis 约为 80 万,8 个 I/O 线程的 Valkey 约为 40 万,单线程的 Redis 和 Valkey 约为 20 万。在每秒 20 万到 160 万次请求之间,HotKV 的 p99 保持在 0.59 到 0.76 毫秒,Dragonfly 为 0.71 到 1.48 毫秒。负载较轻时,多线程产品的 p99 持平,pub/sub 投递也持平。
为什么用固定速率做 Redis 延迟基准测试
吞吐量测试会把服务器推到极限,并报告它处理了多少请求。这很难说明单个请求要等多久。延迟测试则固定客户端每秒发送的请求数,并测量每个请求花费的时间。这样服务器承受的负载与其他产品相同,时间才可以比较。
这类测试有一个陷阱。memtier_benchmark 是闭环工具,客户端要等收到响应后才发送下一个请求。如果服务器跟不上,客户端只会少发请求,而它已发出的请求的延迟会比实际情况看起来更好。因此,只有当达到的速率至少是所要求速率的 97% 时,我们才把这一级算作维持住。未通过的级别在表中标为“NS”(未维持),也不显示其延迟。
我们测试了什么
机器
- 服务器和负载生成器。 位于 eu-south-2a 的 AWS 集群置放群组中的
c8a.12xlarge实例(AMD EPYC 9R45,48 核,无 SMT,96 GiB,22.5 Gbit/s 网络),运行 Ubuntu 24.04。一个实例运行负载生成器,另一个运行服务器。 - 一次只测一个产品。 每个产品单独在服务器上运行,因此没有任何重叠,也没有任何东西共用网络。每个服务器进程都绑定到 CPU 0 至 39,并关闭持久化和保护模式。
产品
- HotKV 0.3.0,40 个线程。
- Dragonfly 2.0.2,40 个 proactor 线程。
- Redis 8.10.3 和 Valkey 9.1.3,各运行两次,一次使用默认的单线程配置,一次使用
--io-threads 8。
每次运行的启动命令行和 CONFIG GET 的实时输出都与其结果一起保存。
负载与步骤
数据集为 1,000,000 个键,值为 256 字节,流水线深度为 1,因此每个请求都要等待自己的响应。负载有只读 GET,以及 1 次写入对 10 次读取的混合。每一级运行 20 秒,共两次,我们报告两次的平均值。memtier_benchmark 使用了按连接的速率限制,并记录了 HDR 直方图。我们测试了两种连接数。
- 816 个连接(24 个线程,每个 34 个连接),速率从每秒 20,000 到 240 万次请求。
- 48 个连接(4 个线程,每个 12 个连接),速率最高到每秒 300,000 次请求。超过这个值,48 个连接无法达到该速率,因为每个连接发送的速度不会超过它收到响应的速度。
结果
先是 GET 表,每种连接数一张,然后是 pub/sub。
816 个连接
每个单元格是 GET 的 p50 / p99,单位为毫秒。“NS”表示未维持,括号中是实际达到的速率。短横线表示该产品的扫描已经停止。
| 请求/秒 | HotKV | Dragonfly | Redis 单线程 | Redis 8 个 I/O 线程 | Valkey 单线程 | Valkey 8 个 I/O 线程 |
|---|---|---|---|---|---|---|
| 19,584 | 0.38 / 1.81 | 0.48 / 1.90 | 1.63 / 5.29 | 0.68 / 2.07 | 1.59 / 5.13 | 0.76 / 2.63 |
| 99,552 | 0.24 / 0.76 | 0.27 / 1.76 | 2.60 / 5.12 | 0.40 / 0.98 | 2.65 / 5.13 | 1.71 / 3.19 |
| 199,920 | 0.25 / 0.59 | 0.25 / 1.34 | 2.91 / 5.60 | 0.55 / 1.11 | 3.02 / 5.81 | 1.11 / 2.15 |
| 399,840 | 0.27 / 0.63 | 0.27 / 1.48 | NS (258k) | 0.62 / 1.23 | NS (259k) | 1.24 / 1.49 |
| 799,680 | 0.28 / 0.75 | 0.28 / 1.26 | - | 0.68 / 1.18 | - | NS (670k) |
| 1,199,520 | 0.28 / 0.67 | 0.28 / 1.05 | - | NS (1,078k) | - | - |
| 1,599,360 | 0.28 / 0.64 | 0.28 / 0.71 | - | - | - | - |
| 2,399,856 | NS (2,284k) | NS (2,281k) | - | - | - | - |
混合负载给出了同样的结果。在每秒 20 万到 160 万次请求之间,HotKV 的 p99 为 0.54 到 0.75 毫秒,各产品能够维持的点与 GET 相同。全部数据都在结果文件夹中。
如何看单线程行
在 816 个连接下,单线程 Redis 和 Valkey 1.6 到 3 毫秒的中位数并不是它们稳态下的延迟。使用速率限制时,memtier_benchmark 会让全部 816 个连接在同一时刻发送。单线程服务器必须逐个处理这一批 816 个请求,所以一个请求的中位数包含了它在队列中的位置。我们进行了下面的 48 个连接的测试来消除这个影响。
48 个连接
单元格的含义与上面相同,只包含 GET。
| 请求/秒 | HotKV | Dragonfly | Redis 单线程 | Redis 8 个 I/O 线程 | Valkey 单线程 | Valkey 8 个 I/O 线程 |
|---|---|---|---|---|---|---|
| 9,984 | 0.14 / 0.54 | 0.14 / 0.37 | 0.21 / 0.89 | 0.17 / 0.92 | 0.21 / 0.91 | 0.20 / 0.81 |
| 49,968 | 0.10 / 0.28 | 0.11 / 0.28 | 0.21 / 0.41 | 0.13 / 0.28 | 0.21 / 0.43 | 0.21 / 0.44 |
| 99,984 | 0.09 / 0.28 | 0.10 / 0.28 | 0.20 / 0.40 | 0.13 / 0.28 | 0.20 / 0.38 | 0.19 / 0.35 |
| 199,968 | 0.08 / 0.27 | 0.08 / 0.27 | 0.20 / 0.35 | 0.10 / 0.27 | 0.21 / 0.36 | 0.11 / 0.28 |
| 300,000 | 0.08 / 0.27 | 0.08 / 0.27 | NS (231k) | 0.09 / 0.26 | NS (233k) | 0.09 / 0.26 |
pub/sub 投递时间
我们用 pubsub-sub-bench 测量了从发布到投递给订阅者的时间,使用 64 个发布者、100 个订阅者和 128 字节的负载。每条消息发给一个订阅者。单元格为 p50 / p99,单位为毫秒。
| 投递/秒 | HotKV | Dragonfly | Redis 单线程 | Redis 8 个 I/O 线程 | Valkey 单线程 | Valkey 8 个 I/O 线程 |
|---|---|---|---|---|---|---|
| 约 21,000 | 0.10 / 0.71 | 0.10 / 0.65 | 0.11 / 0.74 | 0.11 / 0.62 | 0.11 / 0.76 | 0.12 / 0.78 |
| 约 107,000 | 0.10 / 1.02 | 0.12 / 0.92 | 0.10 / 0.80 | 0.11 / 0.63 | 0.10 / 0.82 | 0.10 / 0.86 |
| 约 215,000 | 0.11 / 1.20 | 0.13 / 1.13 | 0.51 / 1.03 | 0.20 / 0.73 | 0.57 / 1.07 | 0.12 / 1.22 |
所有产品的投递都在同一范围内。在最高负载下,单线程产品的中位数更高,为 0.51 和 0.57 毫秒,而 HotKV 为 0.11 毫秒。
我们还需要给 pubsub-sub-bench 打补丁。它把以毫秒为单位的发布时间与以微秒为单位的接收时间做了比较。补丁在结果文件夹中。
结果说明了什么
这些表显示:高负载下 HotKV 和 Dragonfly 领先,轻负载下持平,单线程的 Redis 和 Valkey 有一个上限。
HotKV 和 Dragonfly 在每秒 160 万次请求之内保持了较低的尾部延迟
两者在 816 个连接下都维持了每秒 160 万次 GET,中位数为 0.28 毫秒。HotKV 的 p99 从每秒 20 万次请求起介于 0.59 和 0.76 毫秒之间。Dragonfly 的介于 0.71 和 1.48 毫秒之间,在 160 万时两者很接近(0.64 对 0.71 毫秒)。带 I/O 线程的 Redis 和 Valkey 在更低的负载下就无法维持该速率,单线程的 Redis 和 Valkey 则在约 26 万时无法维持。
轻负载下多线程产品持平
在 48 个连接、最高每秒 300,000 次请求时,HotKV、Dragonfly 和 8 个 I/O 线程的 Redis 的 p99 都约为 0.27 毫秒。HotKV 的中位数最低,从每秒 100,000 次请求起为 0.08 到 0.09 毫秒,Dragonfly 为 0.08 到 0.10 毫秒。0.01 毫秒的差异在配置其他部分可能造成的范围之内,因此我们不把它当作领先。
单线程的 Redis 和 Valkey 在每秒约 23 万次时达到上限
在 48 个连接下,它们的中位数约为 0.2 毫秒,p99 为 0.35 到 0.43 毫秒,并且没有维持住每秒 300,000 次请求(约 231,000 和 233,000)。这是这套硬件和这种负载下单个线程的上限。这就是 Redis 和 Valkey 通常以多个进程或集群方式运行的原因,就像我们的集群基准测试那样。
局限
这些是 HotKV Ltd 对上述版本和配置的测量。它们不是关于这些产品其他版本、配置或负载的结论。
测试配置
- 一台服务器,一台负载生成器。 每一级重复两次,使用一组机器,在同一天完成。我们没有测量机器之间或不同日期之间的差异。
- 我们选择的配置。 Redis 和 Valkey 使用默认的单线程配置和
--io-threads 8运行,除此之外我们没有对它们做调优。其他设置可能改变它们的数字。如果您认为这里的某个设置对某个产品不利,请告诉我们,我们会核实并公布结果。 - 工具的突发效应。 在 816 个连接下,单线程产品的中位数被
memtier_benchmark速率限制的工作方式抬高了,如上所述。
没有测量的内容
- 数据。 更大或分布不均的值、每个键的内存和持久化。所有服务器的持久化都已关闭。
- 模式。 集群模式、分片 pub/sub、TLS、复制和故障转移。
- pub/sub 扇出。 一条消息发给多个订阅者。
Redis、Valkey 和 Dragonfly 是其各自所有者的商标。提到它们只是为了说明我们测量的软件,并不意味着赞助、认可或隶属关系。
自行复现
扫描脚本、每台服务器的启动命令行和实时配置、pubsub-sub-bench 补丁以及所有原始结果都在基准测试仓库中。延迟脚本是 harness/lat_sweep.sh,pub/sub 脚本是 harness/ps_sweep.sh。raw 文件夹中每项测试有一个归档,内含 memtier_benchmark 的 JSON、HDR 直方图以及每次运行时服务器的 CPU 使用情况。
亲自试用
HotKV Cloud 为您运行 HotKV。开始使用 HotKV Cloud,或联系销售,用您自己的工作负载来对比 HotKV。
常见问题
HotKV 的延迟比 Redis 低吗?
在有负载的情况下、在我们测试的速率下,是的。在 816 个连接、每秒 200,000 次请求时,HotKV 的 p99 为 0.59 毫秒,8 个 I/O 线程的 Redis 为 1.11 毫秒,单线程 Redis 为 5.60 毫秒。在 48 个连接的轻负载下,多线程产品的 p99 持平,约为 0.27 毫秒。
为什么固定请求速率?
速率固定时,每个产品承受相同的负载,延迟因此可以比较。吞吐量测试显示的是服务器在极限时能处理多少,很难说明单个请求要等多久。
“未维持”是什么意思?
产品达到的速率低于我们要求的请求速率的 97%。memtier_benchmark 是闭环工具,所以过载的服务器会让客户端少发请求,其余请求的延迟看起来会比实际更好。我们不显示这些级别的延迟。
pub/sub 投递时间的对比如何?
在我们测试的三种负载下,所有产品的投递都在同一范围内,较低的两种负载下中位数约为 0.1 毫秒。上面的表中有全部数字。
我可以复现这项 Redis 延迟基准测试吗?
可以。脚本、配置和所有原始结果都在基准测试仓库中。您需要同一网络中的两台服务器、一台负载生成器以及这四种产品。



继续讨论
评论
对方法有疑问?在您的硬件上得到了不同的结果?欢迎分享您的发现。评论经审核后才会显示。