跳至主要内容

RabbitMQ 性能测量,第一部分

·阅读时长:6 分钟
Simon MacMullen

今天我想谈谈 RabbitMQ 性能的某些方面。影响 RabbitMQ 服务器整体性能的变量非常多,今天我们将尝试调整其中一些变量,看看能发现什么。

这篇文章的目的是不是要告诉你 RabbitMQ 是世界上最快的消息代理 - 它通常不是(虽然我们认为我们仍然很不错)- 而是让你了解在不同情况下可以预期什么样的性能。

所有显示的图表和统计数据都是在配备双 Xeon E5530 和 40GB 内存的 PowerEdge R610 上测量的。主要是因为它是我们手边最快的机器。一个主要的不足之处是我们让客户端和服务器运行在同一台机器上 - 仅仅是因为我们可用的硬件有限。我们使用了 RabbitMQ 2.8.1(在大多数情况下)和启用了 HiPE 编译的 Erlang R15B。

顺便说一下,生成所有这些统计数据的代码在 rabbitmq-java-client 的 bug24527 分支中可用(虽然目前它还比较粗糙)。最终它将被合并到默认分支中,并且变得更容易使用。我们希望如此。

RabbitMQ 2.8.0+ 中的流量控制

但首先,我需要介绍 RabbitMQ 2.8.0+ 中的一个新功能 - 内部流量控制。RabbitMQ 在内部由多个 Erlang 进程组成,这些进程彼此传递消息。每个进程都有一个邮箱,其中包含它接收但尚未处理的消息。这些邮箱可以无限增长。

这意味着,除非从网络套接字接收数据的第一个进程是链中最慢的进程(事实并非如此),那么当你的 RabbitMQ 服务器负载很重时,消息可能会无限期地积存在进程邮箱中。或者更确切地说,直到我们耗尽内存。或者更确切地说,直到内存警报发出。此时,服务器将在自行解决问题之前停止接收新消息。

问题是,这可能需要一些时间。以下图表(本篇文章中唯一一张针对 RabbitMQ 2.7.1 制作的图表)显示了一个简单的进程,该进程以最快速度将小消息发布到代理,并以最快速度消费它们,同时关闭确认、确认、持久化等等。我们绘制了发送速率、接收速率和延迟(发送的消息被接收所需的时间)随时间的变化。注意,延迟是按对数刻度显示的。

简单 1 -> 1 自动确认 (2.7.1)

哎呀!这很不愉快。几件事应该很明显

  • 发送速率和接收速率波动很大。
  • 发送速率下降到零持续两分钟(这是内存警报第一次发出)。事实上,内存警报在最后再次发出。
  • 延迟稳步上升(看看刻度 - 我们显示的是微秒,但我们也可以用分钟来衡量它)。

(在 440 秒左右的延迟略微下降是由于在 200 秒之前发布的所有消息都被消费,以及之后的长间隙。)

当然,这只是你在将服务器压榨到极限时所期望的行为。但我们正在进行基准测试 - 我们想这样做。而且无论如何,服务器在生产中也会受到压力。

所以现在让我们看看针对 RabbitMQ 2.8.1 服务器进行的相同实验

简单 1 -> 1 自动确认 (2.8.1)

看起来平静多了!发送速率、接收速率和延迟都近乎恒定。原因是内部流量控制。延迟约为 400 毫秒(与负载较小的服务器相比,这仍然很高,原因我将在稍后讨论)。

这些图表没有显示内存使用量,但故事是一样的 - 在这种情况下,2.7.1 会消耗大量内存并反弹内存警报阈值,而 2.8.1 会使用相当稳定、相当低的内存量。

链中的每个进程都会向可以向其发送消息的进程发出信用。进程在发送消息时消耗信用,并在接收消息时发出更多信用。当进程用完信用时,它将停止向其上游进程发出更多信用。最终,我们会到达从网络套接字读取字节的进程。当进程用完信用时,它将停止读取,直到获得更多信用。这与 2.7.1 代理的内存警报发出时的情况相同,只是它每秒发生多次而不是花费几分钟,而且我们对内存的使用控制得更多。

那么这 400 毫秒的延迟从哪里来呢?好吧,在管道中的每个阶段仍然有消息排队,所以消息需要一段时间才能从头到尾。这解释了部分延迟。然而,大部分延迟来自整个服务器前面的一个不可见的“邮箱”

  • 操作系统提供的 TCP 缓冲区。在 Linux 上,操作系统允许在 TCP 栈中最多备份 8MB 的消息。当然,8MB 听起来不多,但我们处理的是微小的消息(每个消息都需要路由决策、权限检查等等)。

但重要的是要记住,我们往往会在接近极限时看到最糟糕的延迟。所以这里有一个本周的最后一张图表

1 -> 1 发送速率尝试 vs 延迟

请注意,横轴不再是时间。我们现在显示的是许多类似上面运行的结果,每个点代表一次运行。

在上面的图表中,我们以尽可能快的速度运行,但在这里,我们将速率限制在不同点,直到达到我们所能达到的最大速率。因此,黄线显示了尝试的速率与达成的速率 - 看到它大部分是纯线性 1:1(当我们有剩余容量时,因此如果我们尝试发布得更快,我们会成功)然后在我们达到极限时停止增长我们可以做的事情。

但看看延迟!当发布速率很低时,我们的延迟远小于毫秒。但随着服务器越来越忙,它会逐渐上升。当我们不再能够更快地发布时,我们遇到了延迟障碍 - TCP 缓冲区开始填满,很快消息就会花费数百毫秒才能通过它们。

所以希望我们已经展示了 RabbitMQ 2.8.1 在负载很重时比以前版本提供了更可靠的性能,并展示了当你的消息代理过载时延迟如何直线上升。下周继续收看,了解不同的消息使用方式如何影响性能!

© 2024 RabbitMQ. All rights reserved.