工程

Redis 延迟基准测试:HotKV 对比 Valkey 和 Dragonfly

在 AWS 上对 HotKV、Redis、Valkey 和 Dragonfly 进行的 Redis 延迟基准测试:固定请求速率下的 p50 和 p99、pub/sub 投递时间,以及各产品持平的地方。

Redis 延迟基准测试封面:一块发光的等距服务器板,上面升起一条延迟曲线。

这项 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”表示未维持,括号中是实际达到的速率。短横线表示该产品的扫描已经停止。

请求/秒HotKVDragonflyRedis 单线程Redis 8 个 I/O 线程Valkey 单线程Valkey 8 个 I/O 线程
19,5840.38 / 1.810.48 / 1.901.63 / 5.290.68 / 2.071.59 / 5.130.76 / 2.63
99,5520.24 / 0.760.27 / 1.762.60 / 5.120.40 / 0.982.65 / 5.131.71 / 3.19
199,9200.25 / 0.590.25 / 1.342.91 / 5.600.55 / 1.113.02 / 5.811.11 / 2.15
399,8400.27 / 0.630.27 / 1.48NS (258k)0.62 / 1.23NS (259k)1.24 / 1.49
799,6800.28 / 0.750.28 / 1.26-0.68 / 1.18-NS (670k)
1,199,5200.28 / 0.670.28 / 1.05-NS (1,078k)--
1,599,3600.28 / 0.640.28 / 0.71----
2,399,856NS (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。

请求/秒HotKVDragonflyRedis 单线程Redis 8 个 I/O 线程Valkey 单线程Valkey 8 个 I/O 线程
9,9840.14 / 0.540.14 / 0.370.21 / 0.890.17 / 0.920.21 / 0.910.20 / 0.81
49,9680.10 / 0.280.11 / 0.280.21 / 0.410.13 / 0.280.21 / 0.430.21 / 0.44
99,9840.09 / 0.280.10 / 0.280.20 / 0.400.13 / 0.280.20 / 0.380.19 / 0.35
199,9680.08 / 0.270.08 / 0.270.20 / 0.350.10 / 0.270.21 / 0.360.11 / 0.28
300,0000.08 / 0.270.08 / 0.27NS (231k)0.09 / 0.26NS (233k)0.09 / 0.26

pub/sub 投递时间

我们用 pubsub-sub-bench 测量了从发布到投递给订阅者的时间,使用 64 个发布者、100 个订阅者和 128 字节的负载。每条消息发给一个订阅者。单元格为 p50 / p99,单位为毫秒。

投递/秒HotKVDragonflyRedis 单线程Redis 8 个 I/O 线程Valkey 单线程Valkey 8 个 I/O 线程
约 21,0000.10 / 0.710.10 / 0.650.11 / 0.740.11 / 0.620.11 / 0.760.12 / 0.78
约 107,0000.10 / 1.020.12 / 0.920.10 / 0.800.11 / 0.630.10 / 0.820.10 / 0.86
约 215,0000.11 / 1.200.13 / 1.130.51 / 1.030.20 / 0.730.57 / 1.070.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 延迟基准测试吗?

可以。脚本、配置和所有原始结果都在基准测试仓库中。您需要同一网络中的两台服务器、一台负载生成器以及这四种产品。

觉得有用?

分享这篇文章

继续讨论

评论

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

发表评论

您的显示名称和评论在审核通过后会公开。您的电子邮件地址仅用于上述通知,绝不会显示。您开始输入后,Cloudflare Turnstile 会进行反垃圾检查。 隐私详情.