如何运行基准测试
进行基准测试的原因有很多
- 规模和容量规划
- 产品评估(RabbitMQ 能否处理我的负载?)
- 为您的工作负载发现最佳配置
在这篇文章中,我们将看看运行 RabbitMQ 基准测试的各种选项。但在我们开始之前,您需要一种查看结果和系统指标的方法。
RabbitMQ 可观测性
您已经将每秒 X 条消息路由通过您的 RabbitMQ 集群,并得出结论您已达到峰值吞吐量,但您是否考虑过
- 您的 CPU 在那时已达到最大值,并且无法应对高于该负载的任何峰值
- 您已接近您的网络带宽、磁盘 IOPS 等,并且无法应对高于该负载的任何峰值
- 您的端到端延迟是以分钟为单位,而不是毫秒
- 您丢失了数千条消息,因为您在对 brokers 和网络施加巨大压力时没有使用 confirms 或 acks。
您必须能够看到不仅仅是吞吐量数字。
自 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 基础设施中都运行基准测试,它可以帮助您隔离和优化您的生产/质量保证环境中不理想的区域。
不应该做
- 在不对发布者进行速率限制的情况下运行端到端延迟测试。延迟测试只有在负载在 brokers 容量范围内时才有用。
- 在与您的 RabbitMQ brokers 相同的机器上运行负载生成器(如 perf-test)。
- 在未事先告知您的 IT 运维人员的情况下,在共享的本地环境中运行基准测试。在您的基准测试中用完所有网络带宽往往会让您的 IT 运维人员血压升高。
- 在云 IaaS 中运行基准测试,然后使用这些结果来衡量本地环境的规模。根据 CPU 代、存储配置、网络拓扑等,性能可能存在巨大差异。云之间甚至也存在差异!
一些对性能的常见影响
以下是您在改变基准测试的不同方面时可以预期的一些事情。
- 一个队列有一个吞吐量限制,因此创建几个队列可以提高总吞吐量。但是创建数百个队列会降低总吞吐量。每个 CPU 线程一个或两个队列往往会提供最高的吞吐量。超过这个数量,上下文切换将降低效率。
- 使用发布者确认和消费者确认比不使用它们具有更低的吞吐量。但是,当使用数百个发布者和队列时,发布者确认实际上可以提高性能,因为它们充当了发布者的有效反压机制 - 避免吞吐量的巨大波动(了解更多关于流控制的信息)。
- 发送一条消息,等待发布者确认,然后再发送下一条消息等等,速度非常慢。使用批处理或流水线策略与发布者确认可以显著提高吞吐量(/tutorials/tutorial-seven-java.html 或 /tutorials/tutorial-seven-dotnet.html)
- 不使用消费者预取将增加吞吐量(但这不推荐,因为它可能会压垮消费者 - 预取是我们对 RabbitMQ 施加反压的方式)。预取值为 1 将显著降低吞吐量。通过实验预取来找到适合您的工作负载的值。
- 发送小消息将增加吞吐量(尽管 MB/s 会很低),发送大消息将降低吞吐量(但 MB/s 会很高)。
- 拥有少量的发布者和消费者将导致最高的吞吐量。创建数千个将导致较低的总吞吐量。
- 经典队列比复制队列(镜像/仲裁)更快。复制因子越大,队列速度越慢。
一个常见的模式是,一旦您超过几十个队列和/或客户端,总吞吐量就会下降。连接和连接越多,上下文切换就越多,效率就越低。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 标志)和可用性。您可能对数据丢失和可用性检测感兴趣。重复项和顺序仅在我们 alpha 和 pre-alpha 构建中可能存在新功能错误时才有用。
您可以使用此工具来练习蓝/绿部署或滚动升级,以确保您可以执行操作而不会造成数据丢失和可用性问题。
它还具有高度可定制的 EC2 部署和基准测试编排。可以在不同的 AWS 硬件、RabbitMQ 版本和配置上设置许多并排基准测试。但是,同样,它非常可配置,因此也很复杂。
选项 #5 - RabbitMQ 基准测试 X 项目
好的,所以名称还在制定中,但它代表了一个新项目,我们的目标是使我们自己的团队和更广泛的社区受益,它将成为一统天下的基准测试项目。
该计划是使用像 PerfTest 这样的基准测试工具加上 Kubernetes API,将编排(brokers、磁盘等)和基准测试工具本身结合起来。编排(RabbitMQ、负载生成、可观测性的部署)通常是基准测试中最繁琐的部分,因此我们希望这个项目能够一劳永逸地解决这个问题 - 不仅对我们,而且对每个人。
总结
基准测试可能很难做好,但如果做得正确,它可以提供有价值的信息。关键是尽可能多地使用可观测性工具,并尝试尽可能接近地模拟您的实际工作负载。理解发布者确认和消费者确认的使用、它们在流控制中的作用以及它们对性能的影响至关重要。
在后续涵盖性能的博客文章中,我将包括您需要重新创建负载生成方面的 PerfTest 参数。