跳到主要内容

RabbitMQ 4.1 性能改进

·5 分钟阅读

RabbitMQ 4.1 即将发布,与往常一样,除了新功能外,我们还进行了一些内部更改,这些更改应提供更好的性能。

至少有 4 项值得注意的更改

  1. 仲裁队列更低且更稳定的内存使用率
  2. 消费长仲裁队列时性能大幅提升
  3. WebSocket 连接的性能更好
  4. TCP 连接的内存使用率更低和/或吞吐量更高

仲裁队列:更低的内存使用率

在许多情况下,RabbitMQ 4.1 中的仲裁队列应使用更少的内存。您可能知道,过去仲裁队列具有锯齿状的内存使用模式。它们会为最近的 Raft 操作填充内存缓冲区(缓存),一旦缓冲区满了,就会清空然后再填充。

在 RabbitMQ 4.1 中,这些条目删除得更加频繁,从而在许多条件下实现更稳定的内存使用率。以下是集群最初运行 4.0,然后升级到 4.1 的内存使用情况

Memory usage of a cluster before/after upgrading from 4.0 to 4.1
从 4.0 升级到 4.1 前后集群的内存使用情况

工作负载的确切细节不是非常重要,因为这种差异对于许多不同的工作负载都应该是可见的,但为了完整性,这里列出它们

  • 有 10 个仲裁队列
  • 所有消息的大小均为 1kb
  • 每个队列每秒从单个发布者接收 500 条消息(因此所有队列总共每秒 5000 条消息)
  • 每个队列都有一个消费者(绝大多数消息在发布后 10 毫秒内被消费)
  • 队列实际上是空的,因为所有消息都立即被消费了

值得记住的是,在所有条件下都不能期望如此低且稳定的内存使用率。例如,仲裁队列将队列中消息的元数据保存在内存中,因此,如果队列中有大量消息(消息未立即消费),则此元数据将消耗内存。还有其他因素和内存结构会根据工作负载而增长。尽管如此,在许多常见情况下,内存使用率应该更低且更少突兀。

仲裁队列:卸载磁盘读取

让我们考虑一个完全不同的工作负载 - 消息在队列中累积,然后消费者需要赶上进度以清空队列的工作负载。从历史上看,仲裁队列可能会被大量涌入的消费者压垮,特别是当消息很大且消费者请求大量消息时(要么他们有很大的预取缓冲区,要么有很多消费者,或者两者都有)。在这种情况下,队列可能会因为从磁盘读取旧消息(以将它们分派给消费者)而变得非常繁忙,以至于发布者不得不等待很长时间才能让他们的消息被队列接受。

在 RabbitMQ 4.1 中,此类磁盘读取被卸载到 AMQP 0.9.1 通道或 AMQP 1.0 会话进程(基于使用的协议)。队列需要做的工作少得多,并且可以继续为发布者提供服务。

让我们看一下 4.0 和 4.1 之间发布和消费速率的差异

Influx of consumers, 4.0 to 4.1
消费者涌入,4.0 到 4.1

以下是此图中发生的情况

  1. 我们有两个集群在运行,4.0(绿线)和 4.1(黄线)
  2. 两个集群都接收约每秒 6000 条消息,每条消息 20kb
  3. 最初,没有消费者;因此,消费率为零
  4. 一段时间后,消费者开始并尝试消费消息
  5. 在每个环境中,现在都有 10 个消费者,每个消费者都有 300 条消息的预取缓冲区
  6. 4.0 环境不堪重负 - 发布速率降至每秒仅约 100 条消息
  7. 与此同时,4.1 环境继续为发布者提供服务,没有明显的性能影响
  8. 此外,4.1 环境中的消费率几乎翻了一番
  9. 一旦消费了消息积压,两个环境都可以处理每秒约 7000 条消息的进出

不仅发布者没有受到限制,而且消费者也能够更快地消费消息!

WebSocket 连接的更好性能

为了服务 HTTP 连接,RabbitMQ 使用了一个流行的 Erlang HTTP 服务器,名为 Cowboy(由 Loïc Hoguin 在他加入 RabbitMQ 团队之前很久开发)。RabbitMQ 4.1 将 Cowboy 升级到 2.13.0 版本,该版本显著提高了 WebSocket 性能,适用于所有依赖 Cowboy 的系统,包括 RabbitMQ。因此,升级到 RabbitMQ 4.1 对于任何使用 WebSocket 上的 AMQPMQTTSTOMP 的人来说都应该特别有利。

TCP 缓冲区自动调整

Cowboy 2.13.0 发布博文中描述的一个关键改进是动态 TCP 缓冲区自动调整。对于 WebSocket 连接,Cowboy 中的这些改进会自动使 RabbitMQ 用户受益,因为 Cowboy 处理与 RabbitMQ 的 HTTP 连接。

在 RabbitMQ 4.1 中,我们将相同的 TCP 缓冲区自动调整机制 incorporated 到 AMQP 监听器中,这是一个完全独立的代码路径,不使用 Cowboy(因为 Cowboy 是一个 HTTP 服务器)。 благодаря 这项工作,RabbitMQ 应该为 AMQP 0.9.1 和 1.0 连接使用更少的内存,而不会有明显的性能损失。节省的内存量取决于您当前的缓冲区大小和连接数,但在我们的测试中,它在一个拥有数千个连接的系统中节省了几百兆字节的内存。

值得指出的是,本段讨论的缓冲区是用户空间缓冲区,不应与 recbuf / sndbuf 缓冲区混淆,后者是内核缓冲区。这些缓冲区可以静态配置,如果未配置,则由 Linux 内核自动调整(在其他操作系统上的行为可能有所不同)。

tcp_listen_options.buffer 的值(以前用于控制现在自动调整的缓冲区的大小)将被忽略。

© . All rights reserved.