如何运行基准测试
进行基准测试可能有很多原因
- 容量规划和容量管理
- 产品评估(RabbitMQ 能否处理我的负载?)
- 发现适合您工作负载的最佳配置
在本文中,我们将介绍运行 RabbitMQ 基准测试的各种选项。但在我们开始之前,您需要一种查看结果和查看系统指标的方法。
RabbitMQ 可观测性
您已经通过 RabbitMQ 集群实现了每秒 X 条消息的路由,并得出结论认为您已达到峰值吞吐量,但您是否考虑过:
- 此时您的 CPU 已满负荷运行,无法承受任何高于此负载的峰值。
- 您已接近网络带宽、磁盘 IOPS 等的极限,无法承受任何高于此负载的峰值。
- 您的端到端延迟达到了分钟级,而不是毫秒级。
- 由于您没有使用确认机制或应答机制,导致在给代理和网络带来巨大压力的同时丢失了数千条消息。
您必须能够看到比吞吐量数字更多的信息。
自 3.8.0 版本以来,我们提供了 rabbitmq_prometheus 插件。了解如何让 Grafana、Prometheus 和 RabbitMQ协同工作,从而获得对您的 RabbitMQ 实例的惊人洞察。
查看我们已发布的 Grafana 仪表板,不仅可以了解队列数量、连接数量、消息速率等,还可以从 Erlang 角度了解底层发生了什么。此外,还有无数的系统指标仪表板和代理可供您安装,以查看 CPU、RAM、网络和磁盘 IO 等系统指标。例如,可以查看 node_exporter,它可以提供有关硬件和操作系统行为的洞察。
使用 Prometheus 之类的解决方案的另一个原因是,当您将 RabbitMQ 推向极限时,管理 UI 可能会变得迟缓或无响应。UI 正在尝试在一台可能已经接近 100% CPU 利用率的机器上运行。
一些基准测试的“做”与“不做”
做:
- 使用我们的可观测性工具!
- 尽量使您的基准测试工作负载与您的实际工作负载尽可能匹配,否则您将进行“苹果与橘子”的比较。
- 花时间了解可能影响性能的概念:发布确认、消费者应答、消息大小、队列数量(参见下一标题)。
- 确保承载您的负载生成器的 VM 不是瓶颈。要么过度配置您的负载生成机器,要么对其进行监控(CPU 和网络)。
- 注意具有可突发资源(如 CPU、网络和磁盘)的 IaaS。如果您只查看测试的前 30 分钟,您可能会认为您选择的磁盘足以胜任。如果您让基准测试继续运行,您可能会看到吞吐量在突发期结束后立即下降。
- 请注意,如果您在可能具有复杂网络设置(例如双重 NAT、VPC 网关、负载均衡器、防火墙等)的共享本地环境中运行基准测试,那么您不一定是在测试 RabbitMQ,而是在测试您的 IT 基础设施。
如果您在隔离环境和您的主要 IT 基础设施中都运行基准测试,这有助于您隔离和优化您的生产/质量保证环境中的非最优区域。
不做:
- 在未对发布者进行速率限制的情况下运行端到端延迟测试。延迟测试仅在负载在代理容量范围内时才有用。
- 在与您的 RabbitMQ 代理相同的机器上运行负载生成器(例如 perf-test)。
- 在未事先告知您的 IT 运维人员的情况下,在共享的本地环境中运行基准测试。用掉您基准测试的网络带宽通常会引起 IT 运维人员的注意。
- 在云 IaaS 中运行基准测试,然后使用这些结果来调整本地环境的大小。性能可能会因 CPU 代系、存储配置、网络拓扑等而存在巨大差异。不同云之间甚至也存在差异!
影响性能的一些常见因素
以下是您在调整基准测试的不同方面时可能预期的一些情况。
- 一个队列的吞吐量有限,因此创建几个队列可以提高总吞吐量。但是创建数百个队列将降低总吞吐量。每个 CPU 线程一到两个队列通常能提供最高的吞吐量。超过这个数量,上下文切换会降低效率。
- 使用发布确认和消费者应答比不使用它们具有较低的吞吐量。但是,当使用数百个发布者和队列时,发布确认实际上可以提高性能,因为它们充当发布者的有效反压机制——避免吞吐量的大幅波动(了解有关流控制的更多信息)。
- 发送一条消息,等待发布者确认,然后发送下一条,依此类推,速度非常非常慢。使用批量或带有发布确认的管道策略可以显着提高吞吐量(/tutorials/tutorial-seven-java.html 或 /tutorials/tutorial-seven-dotnet.html)。
- 不使用消费者预取会提高吞吐量(但不推荐,因为它可能使消费者不堪重负——预取是我们对 RabbitMQ 进行反压的方式)。预取值为 1 会显着降低吞吐量。尝试预取以找到适合您工作负载的值。
- 发送小消息会提高吞吐量(尽管每秒兆字节数会较低),而发送大消息会降低吞吐量(但每秒兆字节数会较高)。
- 少量发布者和消费者的组合将产生最高的吞吐量。创建数千个会降低总吞吐量。
- 经典队列比复制队列(镜像/仲裁)更快。复制因子越大,队列越慢。
一种常见模式是,一旦您超过几十个队列和/或客户端,总吞吐量就会下降。连接数越多,上下文切换就越多,效率就越低。CPU 核心数量是有限的。如果您有数千个队列和客户端,那并不是坏事,但请认识到与只有几十个或几百个客户端/队列时相比,您可能无法获得相同的总吞吐量。
选项 #1 - 使用您现有的应用程序
如果您需要进行容量规划基准测试或找到最佳配置,那么使用您现有的应用程序最有可能产生最有用的结果。
合成基准测试的问题在于,它们告诉您您的 RabbitMQ 安装将如何应对所选负载生成器产生的负载,而这可能与您的实际使用情况大相径庭。
使用您的真实应用程序的问题在于,生成负载可能需要一些工作来设置。
其次,除非您已经对其进行了检测,否则您将无法获得端到端延迟指标。当然,您可以添加它。您可以将时间戳添加到消息头中,在消费者中提取该头,然后发布指标。大多数语言都有高效发出指标的库,无需手动编写任何内容(例如 https://micrometer.io/)。还要考虑到,如果没有像 NTP 这样的时钟同步,端到端延迟指标将不准确,即使有,也可能存在抖动。
选项 #2 - Perf Test
PerfTest 是我们推荐的用于对 RabbitMQ 的简单工作负载进行合成基准测试的工具。PerfTest 在 GitHub 上,并有一些不错的说明。要自己运行它,请遵循安装说明。
它甚至有自己的 Grafana 仪表板!
选项 #3 - Perf Test + CloudFoundry
请查看我们在 GitHub 上的workloads 项目。它将向您展示如何在 CloudFoundry 上部署和测试各种工作负载。
选项 #4 - RabbitTestTool
这是一个我个人使用(和构建)的实验性工具,用于进行自动化探索性测试。它是一个强大但复杂的工具,因此可能不是您的理想选择。它更多的是一个 QA 工具,而不是供客户自行基准测试。
但它有一些可能让您感兴趣的功能。
首先,它有一个模型驱动的、基于属性的测试模式,可以检测数据丢失、顺序违规(无 redelivered 标志)、重复交付(无 redelivered 标志)和可用性。数据丢失和可用性检测可能更让您感兴趣。重复和顺序仅在我们可能存在新功能 bug 的 alpha 和 pre-alpha 版本中有用。
您可以使用此工具来练习蓝绿部署或滚动升级,以确保您可以执行操作而不会丢失数据或中断可用性。
它还具有高度可定制的 EC2 部署和基准测试编排。可以设置许多并排的基准测试,使用不同的 AWS 硬件、RabbitMQ 版本和配置。但是,再次强调,由于配置高度灵活,因此也比较复杂。
选项 #5 - RabbitMQ Benchmark X-Project
好的,名字还在开发中,但它代表了一个新项目,我们旨在从中受益,也惠及更广泛的社区,它将是一个统一的基准项目。
计划是使用像 PerfTest 这样的基准测试工具,并结合 Kubernetes API,将编排(代理、磁盘等)和基准测试工具本身结合起来。编排(RabbitMQ、负载生成、可观测性的部署)通常是基准测试中最繁琐的部分,因此我们希望这个项目能一劳永逸地解决这个问题——不仅对我们,也对所有人。
总结
正确进行基准测试可能很困难,但如果做得正确,它可以提供有价值的信息。关键是尽可能多地使用可观测性工具,并尝试尽可能精确地模拟您的实际工作负载。了解发布者确认和消费者应答的用法、它们在流控制中的作用以及它们对性能的影响至关重要。
在后续关于性能的博文中,我将包含您需要用来重现负载生成部分的 PerfTest 参数。