将新的 Redis6 多线程 I/O 与 Elasticache 和 KeyDB 进行比较
人们经常问 Elasticache、Redis 还是 KeyDB 哪个更快。随着 Redis 6 即将推出多线程 I/O,我们觉得现在是时候进行一次全面的比较了!这篇博客比较了 Elasticache、开源 KeyDB 和开源 Redis v5.9.103(6.0 分支)的单节点性能。我们将 بررسی 不同负载和不同工具下的吞吐量和延迟。
#
简史KeyDB 大约一年前推出,是 Redis 的多线程分支,性能有了显著提升。不久之后,亚马逊宣布他们的 增强型 I/O 处理,通过 Elasticache 用于 Redis。Redis 现在正在发布其 6.0 版本中的多线程 I/O 选项。与 Redis6 和 Elasticache 不同,KeyDB 在多个方面采用多线程,包括将事件循环放在多个线程上,网络 I/O 和查询解析并发进行。
因此,有 3 家公司提供 3 种产品,它们都相互兼容,并且都基于开源 Redis:Elasticache 作为 Redis 的优化服务产品提供;RedisLabs 和 Redis 提供核心产品和商业化产品;KeyDB 仍然是 Redis 的一个快速尖端(开源)超集。这篇博客专门探讨性能,但在博客的末尾有一个部分也概述了其他关键区别。
#
测试对于测试,我们使用了 RedisLabs 创建的基准测试工具 Memtier,以及 Yahoo 用于比较许多流行数据库的基准测试工具 YCSB。我们没有使用 KeyDB 内置的基准测试,以避免出现偏见,也因为此测试的吞吐量限制。这里显示的所有结果都可以由任何使用 AWS 的人重现。本博客末尾有一个部分详细说明了如何重现测试以及为避免瓶颈/测试差异/偏差而应考虑的因素。
#
使用 Memtier 进行吞吐量测试Memtier 是 RedisLabs 设计的基准测试工具,用于对 Redis 进行负载测试。它擅长产生高吞吐量,并且与 KeyDB 和 Elasticache 兼容。下面的测试在几种不同大小的 AWS r5 实例上运行。
我们使用 KeyDB 运行多达 8 个服务器线程,使用 Redis 运行 8 个 I/O 线程。我们发现 Redis 使用 4 个以上 I/O 线程通常不会有进一步的改进,但我们尝试了不同的组合并使用了显示最佳吞吐量的线程数。
Elasticache 是一项由 AWS 管理的服务,因此我们让他们提供优化的配置。
所有测试均在同一区域通过私有 IP 执行,并取多次测试的平均值。有关重现这些基准测试的详细信息,请参阅本博客的末尾。
下表显示了使用加载数据库时的吞吐量(ops/秒)
正如您所看到的,随着核心数量的增加,KeyDB 在性能吞吐量方面显示出比 Redis 和 Elasticache 显著的优势。即使 Redis6 具有多线程 I/O,它在垂直扩展能力方面仍然落后于 KeyDB 和 Elasticache。
在 r5.large 实例上,Elasticache 的性能略高,但我们注意到 Elasticache 在 r5.xlarge 上的性能有所下降(在不同时间进行了多次测试)。我们不确定这背后的原因。
Memtier 测得的延迟数字最终会达到几毫秒,因为它是在机器/节点的最大吞吐量下测量的。它不代表平均负载甚至高负载,而更多地代表最坏情况。为了在测试延迟时进行良好的相对比较,我们借助 YCSB 来测量给定负载和吞吐量下的延迟。
#
使用 YCSB 进行吞吐量测试YCSB 是 Yahoo 的基准测试工具,兼容当前许多流行的数据库。该工具具有很大的灵活性,可以处理不同的“工作负载”,代表更真实的加载场景。
以下测试着眼于运行几种不同工作负载时的最大吞吐量
- 工作负载 A:更新密集型工作负载(50:50 读/写)
- 工作负载 B:读取为主的工作负载(95:5 读/写)
- 工作负载 C:只读
- 工作负载 D:读取最新工作负载 - 最近插入的记录最受欢迎
- 工作负载 E:短范围——即线程对话
- 工作负载 F:读-修改-写
有关上述工作负载的完整说明,请点击此链接
下表显示了在预加载数据集上针对多种工作负载的最大每秒操作数。“加载操作/秒”来自加载工作负载“a”数据集。根据 YCSB 建议,此数据集用于所有工作负载测试。
使用 YCSB,KeyDB 在所有测试的工作负载下都达到了最高的吞吐量。Elasticache 紧随其后,其次是 Redis6。值得注意的是,Redis6 仍然比没有 I/O 线程的 5 版本更快。
#
使用 YCSB 进行延迟测试YCSB 是一个测量延迟的绝佳工具。它允许您指定目标吞吐量,并测量在该流量下相关的延迟。在不同的负载下,它提供了良好的可见性,让您了解您的数据库在不同工作负载和不同流量下的性能。它还可以极大地帮助您选择用于实例的机器大小。
以下测试着眼于“工作负载 a”(50/50 读/写)和“工作负载 b”(主要是写)。UPDATE 延迟趋势与下面所示的 READ 延迟趋势相似。这些工作负载通常用于运行缓存层数据库。
请记住,延迟测量单位是微秒,值越低越好
上面显示的趋势表明,随着实例接近其容量吞吐量,延迟显著增加。KeyDB 可以处理比 Redis6 明显更多的吞吐量,并且比 Elasticache 略多,因此能够在更高负载下保持更低的延迟。
KeyDB、Elasticache 和 Redis 6 在轻到中度流量下都具有相似的延迟。只有当容量开始达到更高负载时,才会出现差异。当在工作负载 a/c/d/e/f 上运行时,上面的趋势看起来非常相似,但幅度略有不同。这里的行为是重要的收获。
“工作负载 e”的响应差异最大,因此我们还将显示下面的延迟趋势。“工作负载 e”,如 YCSB 所述,可能常用于“线程对话,其中每次扫描都是针对给定线程中的帖子”。
如您所见,趋势行为相似,但由于工作负载的性质,数据集与其他数据集不同。KeyDB 仍然保持较低的延迟。
#
火焰图对于那些喜欢火焰图,并寻找一些视觉表示的人,我们运行了一些 Redis5、Redis6 和 KeyDB 之间的火焰图供您查看。我们无法访问 Elasticache 服务器,因此无法为其运行它们。这些火焰图是在基准测试期间运行的。您可以在下面找到 SVG 文件的链接,以仔细查看并查看细分。
memtier-redis5, memtier-redis6, memtier-keydb, ycsb-redis5, ycsb-redis6, ycsb-keydb
#
KeyDB、Elasticache 和 Redis 有何不同?每种产品都始于基于开源 Redis 构建,并保持与其完全兼容。然而,每种产品都走向了略有不同的方向。
那么,除了性能,这些产品之间还有哪些关键区别?
KeyDB
- KeyDB 是开源的。我们专注于内存效率、高吞吐量和性能,并且在不久的将来会有一些重大改进。这使我们能够提供原本永远不会成为开源 Redis 一部分的特性。我们专注于通过提供主动复制和多主选项等特性来简化用户体验。我们还有额外的命令,如子键 EXPIRES 和 CRON。
- KeyDB Pro 产品包括 MVCC、FLASH 支持等。
Elasticache
- Elasticache 提供其自己的 Redis 分支作为优化服务。这是一项仅通过 AWS 提供的付费服务,因此您无法在本地运行。因为它完全托管,所以实例管理、副本和集群由 AWS 处理,用户只能进行有限的高级决策。配置参数也超出您的控制范围。
Redis
- Redis 是开源的,存在时间最长。它对代码库采用极简主义方法,这与 KeyDB 不同。
- RedisLabs 是 Redis 的付费版本,提供完全托管的解决方案以及专有模块。RedisLabs 提供带有其付费版本的 FLASH,并且可以在本地托管。然而,定价可能相当高。
#
多线程差异虽然 Redis6 现在有多线程 I/O,并且 Elasticache 使用其增强的网络 I/O 线程,但 KeyDB 的工作原理是将正常的 Redis 事件循环运行在多个线程上。网络 I/O 和查询解析是并发进行的。每个连接在接受时都被分配一个线程。对核心哈希表的访问由自旋锁保护。因为哈希表访问速度极快,所以此锁的争用较低。事务在 EXEC 命令的持续时间内持有锁。模块与 GIL 协同工作,仅当所有服务器线程暂停时才获取 GIL。这维护了模块期望的原子性保证。
#
重现基准测试我们无法通过客户端访问 `config get <>` 来查看 elasticache 的配置。然而,从设置来看,elasticache 依赖副本进行数据备份,并提供诸如“每日备份”等 rdb 选项到 s3。查看 `info persistence`,您可以看到在基准测试期间没有发生后台保存,这在 keydb.conf 或 redis.conf 中是标准做法。我们通常的基准测试保持默认设置,包括后台保存,但为了测试的公平性,我们通过向 Redis 和 KeyDB 传递 `--save “”` 选项来禁用后台保存。在大多数情况下,这是不明显的。
为了帮助优化 Redis,并遵循他们的建议,我们还更新了以下 Linux 参数
- 将 /proc/sys/net/core/somaxconn 更改为 65536
- echo never > /sys/kernel/mm/transparent_hugepage/enabled
- sysctl vm.overcommit_memory=1
#
避免瓶颈- 由于 KeyDB 的多线程和性能优势,我们通常需要一个比 KeyDB 运行的机器大得多的基准测试机器。我们发现需要一台 32 核的 m5.8xlarge 才能使用 memtier 产生足够的吞吐量。这支持多达 16 核 KeyDB 实例(中型到 4xlarge)的吞吐量
- 使用 Memtier 时,运行 32 个线程。
- 在同一网络上运行测试。如果比较实例,请确保您的实例位于同一可用区 (AZ)。例如,两个实例都在 us-east-2a 中。
- 使用私有 IP 地址运行。如果您使用 AWS 公有 IP,则网络可能会有更多变化。
- 注意通过代理或 VPC 运行。使用此类方法、防火墙和其他层时,很难确定瓶颈可能是什么。最好在简单的环境中(同一 VPC 内)进行基准测试,然后添加层以确保您已优化。
- 在比较不同的机器实例时,请确保它们位于相同的可用区(AZ)中,并尽可能在相近的时间进行测试。一天中的网络吞吐量确实会发生变化,因此在相近的时间进行测试可以提供最具代表性的相对比较。
- KeyDB 是多线程的。运行时请确保指定多个线程。
#
KeyDB我们所有的测试都通过以下参数执行
请记住,我们的安全组不向公众公开端口 6379,仅向我们的测试实例公开。您可以使用 `--requirepass mypassword` 参数添加密码。
#
Redis使用 Redis6,您需要使用新的 `io-threads` 参数。您可以将其设置得尽可能高。我们发现 4-8 之间效果最佳,但设置时请记住机器上可用的 CPU 数量。
#
Elasticache您可以从这里开始:https://aws.amazon.com/elasticache/。前往“创建集群”并记住以下参数
- 选择“Redis”并确保“启用集群模式”未选中。
- 设置您的实例名称和版本 5.0.6(最新)兼容性。
- 选择您的机器大小/类型并将副本设置为 0。
- 将您的 AZ 选择为与基准测试机器相同。
- 创建机器后,您可以使用“主端点”作为连接的主机地址。
#
Memtier确保您至少在 m5.8xlarge 上运行。按照此处的说明安装 memtier。您可以从加载数据集开始,使用:
然后运行一个正常的测试,使用
您可以尝试其他参数和选项。有关详细信息,请参阅 --help 选项。
#
YCSB请参阅 github repo 获取安装说明,并参阅 wiki 获取有关使用 YCSB、工作负载、加载、运行等的更多详细信息。以下是我们用于生成基准测试结果的基本命令。有关更多信息,请参阅 wiki。
我们首先加载数据,然后执行测试。默认设置较小,因此我们为测试指定了 1000 万条记录和 1000 万次操作。请参阅此处的工作负载属性。
当客户端数量较少时,基准测试可能对网络延迟敏感。为了获得相当一致的结果和最大吞吐量,我们使用 350 个客户端线程。您的结果将输出到您指定的文件。
本博客中执行的所有 YCSB 测试均在 r5.4xlarge 实例(测试机器)上完成,基准测试机器为 m5.8xlarge。