跳至主内容

RabbitMQ 4.1 性能改进

·6 分钟阅读

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 缓冲区自动调整机制整合到了 AMQP 监听器中,这是一个完全独立的代码路径,不使用 Cowboy(因为 Cowboy 是一个 HTTP 服务器)。感谢这项工作,RabbitMQ 应该为 AMQP 0.9.1 和 1.0 连接占用更少的内存,而没有明显的性能损失。节省的内存量取决于您当前的缓冲区大小和连接数,但在我们的测试中,在一个拥有数千个连接的系统中节省了几百兆字节的内存。

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

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

© . This site is unofficial and not affiliated with VMware.