RabbitMQ——调优参数

2023-05-16

【前言】

前面几篇文章讲述了rabbitmq消息存储的相关原理,也提到了有些参数可以进行配置。这些配置参数的微调在不同的场景中会有不同的效果。本文对其中一些参数进行说明,同时以实测数据结合性能分析工具进行剖析。

【相关参数说明】

  • queue_index_embed_msgs_below

控制消息的存储位置。是独立存储到msg_store中,还是嵌入消息的索引一并存储。默认值是4096(字节),即小于4KB的消息会嵌入到消息索引中一并存储。

注:4KB包括消息内容以及消息的属性等元数据信息,其中消息的元数据信息占用至少300字节。

  • queue_index_max_journal_entries

索引文件写磁盘之前能缓存的最大日志条数。默认值为32768,即消息的publish、delivery、ack操作数达到32768次后,会将日志文件journal.jif中的内容写到对应的索引文件(*.idx)中。索引文件的存储细节戳这里。

注:该值是针对队列的,并非全局设置的值。

  • msg_store_io_batch_size

对于非lazy队列,触发paging时,内部Q1,Q2,delta,Q3,Q4之间每次消息挪动的最大值。默认值为4096,即Q1->Q2每次最多移动4096*2=8192条消息,同样Q2->delta、Q4->Q3、Q3->delta每次最多移动8192条消息。

  • credit_flow_default_credit

流控的信用配置,作用于 reader->channel->queue之间。

默认值为{400,200}。

  • msg_store_credit_disc_bound

msg_store方式的消息存储的流控信用配置,即作用于queue->msg_store之间。默认值为{4000,800}。

【参数调优】

  • queue_index_max_journal_entries

先来看一组测试数据

测试场景是这样的:

  1. 16个生产者分别向64个持久化队列不间断发送消息,队列设置为lazy模式;每条消息大小为4KB,属性设置为持久化;

  2. queue_index_embed_msgs_below设置为10240,即消息会嵌入索引一并存储;

  3. 数据整体存储在SSD上;

  4. queue_index_max_journal_entries的值分别设置为1024、2048、4096、8192、32768。

在只有生产者场景下与同时有生产者消费者场景下(每个队列1个消费者,收到消息不做任何处理)的测试情况:

生产速度表示仅有生产者场景下,16个生产者累计的生产速度。

生产消费速度表示同时有生产者消费者场景下,16个生产者累计的生产速度(消费速度与生产速度几乎持平,即生产速度和消费速度均为图中数据所示)

通过eprof分析队列进程函数调用与耗时如下图所示:

从上面实测性能与eprof的分析可以得出一个结论:随着值得变大,每次sync的耗时也在逐渐变大,因为每次需要写入的数据量变大了,因此相应的吞吐量也就下降了。

但这里有一个奇怪的地方:设置为32768时,为什么sync的耗时不多,但吞吐量也不高呢?

我们仔细看下eprof分析的数据:

发现虽然sync的耗时不长,但累计sync的次数明显多了。理论上收到43078条消息,理论上触发写idx的次数应该是43078/32768=1次,每次写32768/16384=2个idx文件,因此也就是2次sync操作。然而实际上却有371次sync,根据源码分析应该是队列一段时间内没收到任何消息后的定时器超时,触发了将journal.jif文件同步到磁盘上。实际上eprof给出的数据也确实是如此,timeout的调用次数为367次,基本能对上。

那为何又会出现这种情况呢?再次测试,分别在不同的时间段使用eprof进行分析,发现一开始sync的耗时非常大,然后逐步下降并稳定在一个范围内。在这个过程中,生产速度也是逐步下降,同时生产者对应通道进程的缓存中开始出现消息堆积,最终维持在一个水平线上下。

因此前面随着配置值得变大,每次sync的耗时也逐步变大的结论是没有问题的。但出现上面的现象推测一方面与流控有关,一方面与通道进程的消息堆积有关(堆积后,每次GC会有一定的耗时)


  • credit_flow_default_credit

测试场景与前面一样,credit_flow_default_credit的值分别设置为{400,200}、{800,200}、{1000,200}、{2000,200}下的测试情况如下所示:

eprof的分析与web上观察通道进程mailbox、gen_server2 buffer的堆积情况如下表所示:

从上面两幅图可以看出,信用流控配置值越大,整体吞吐量反而下降,但下降不明显。另外sync的耗时差别不算大,但通道进程gen_server2 buffer堆积的数量在逐步增加,并且通道进程GC的耗时也在逐渐增加。因此可推测,信用流控配置设置越大,通道进程堆积会越多,GC耗时也就越大,这样整体吞吐量也就会下降。

【总结】

本文总结了几个调优相关的参数,也在特定场景下对其进行了测试说明。但性能不仅仅和这两个参数有关,队列个数、消息大小、消息属性、内存水位、队列是否使用lazy模式、机械盘还是SSD进行存储,等等都会有一定的影响。此外,erlang层面还会有一些参数可以微调,因此不同场景下还需要结合实际需要进行参数的调优。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RabbitMQ——调优参数 的相关文章

  • spring中rabbitmq监听器的异常处理

    使用spring 我是rabbitmq的新手 我想知道我错在哪里 我编写了一个rabbitmq连接工厂和一个包含侦听器的侦听器容器 我还为侦听器容器提供了错误处理程序 但它似乎不起作用 我的春豆
  • 在使用 FromEventPattern 订阅之前捕获事件

    我正在使用 Rx 框架编写消息监听器 我面临的问题是 我正在使用的库使用一个消费者 每当消息到达时就会发布事件 我已经设法通过以下方式消费传入的消息Observable FromEventPattern但我对服务器中已有的消息有疑问 目前我
  • 为什么我无法使用 python 建立与rabbitMQ的连接?

    我正在学习如何使用rabbitMQ 我正在 MacBook 上运行rabbit MQ 服务器并尝试与 python 客户端连接 我按照安装说明进行操作here http www rabbitmq com install homebrew h
  • 为什么 Celery 工作人员给出“OSError:套接字已关闭”

    我的与rabbitMQ一起工作的celery工作人员在工作几分钟后不断给我一个套接字错误 见下文 我想知道问题的主要原因是什么 我认为这可能是防火墙 但是 禁用防火墙并没有解决问题 我正在 Windows 10 机器上工作 C Users
  • 在 Red Hat 上安装 RabbitMQ - 错误的 Erlang 版本

    我正在尝试按照以下说明在 Red Hat Enterprise Linux 7 64 位工作站版本 的评估虚拟机上安装 RabbitMQhttps www rabbitmq com install rpm html https www ra
  • 如何在nodejs中验证rabbitmq?

    错误 握手被服务器终止 403 ACCESS REFUSED 消息 ACCESS REFUSED 使用身份验证拒绝登录 旋转机制平原 有关详细信息 请参阅代理日志文件 我单独尝试了 authMechanism PLAIN AMQPLAIN
  • 无法在Windows上启用rabbitmq管理插件

    所以 这就是我所做的 在我的 Windows x64 位机器上安装了 Erlang 安装 RabbitMQ 启动 RabbitMQ 服务 这一步我没有任何错误 但是 当我尝试启用rabbitmq management时 我在控制台中收到一些
  • RabbitMQ - 升级到新版本并收到很多“PRECONDITION_FAILED Unknown Delivery Tag 1”

    刚刚升级到新版本的 RabbitMQ 2 3 1 现在出现以下错误 PRECONDITION FAILED unknown delivery tag 1 随后通道关闭 这适用于较旧的 RabbitMQ 无需客户端更改 在应用程序行为方面 当
  • Spring AMQP RabbitMQ 如何直接发送到Queue而不需要Exchange

    我正在使用 Spring AMQP 和 Rabbitmq 模板 如何直接将消息发送到队列而不使用Exchange 我该怎么做 我该怎么做 你不能 发布者不知道队列 只是交换和路由密钥 但是 所有队列都绑定到默认交换器 以队列名称作为其路由键
  • 为什么需要消息队列来与 Web 套接字聊天?

    我在互联网上看到了很多使用 Web 套接字和 RabbitMQ 进行聊天的示例 https github com videlalvaro rabbitmq chat https github com videlalvaro rabbitmq
  • MongoDB 架构设计 - 实时聊天

    我正在启动一个项目 我认为该项目特别适合 MongoDB 因为它提供的速度和可扩展性 我目前感兴趣的模块是与实时聊天有关的 如果我要在传统的 RDBMS 中执行此操作 我会将其分为 频道 一个频道有很多用户 用户 一个用户有一个频道但有多条
  • Celery 任务状态取决于 CELERY_TASK_RESULT_EXPIRES

    据我所知 任务状态完全取决于 CELERY TASK RESULT EXPIRES 设置的值 如果我在任务完成执行后检查此间隔内的任务状态 则返回的状态为 AsyncResult task id state 是正确的 如果没有 状态将不会更
  • 如何使用 Celery、RabbitMQ 和 Django 确保每个用户的任务执行顺序?

    我正在运行 Django Celery 和 RabbitMQ 我想要实现的是确保与一个用户相关的任务按顺序执行 具体来说 一次执行一个 我不希望每个用户执行任务并发 每当为用户添加新任务时 它应该取决于最近添加的任务 如果此类型的任务已为此
  • 在 docker-compose 文件中提供rabbitmq.conf会给出“sed:无法重命名/etc/rabbitmq/sedMaHqMa:设备或资源繁忙”

    我的 docker compose 看起来像这样 version 3 2 services mq hostname HOST NAME ports 5671 5671 5672 5672 15671 15671 15672 15672 en
  • 在 Celery 工作线程中捕获 Heroku SIGTERM 以优雅地关闭工作线程

    我对此进行了大量研究 令我惊讶的是我还没有在任何地方找到一个好的答案 我正在 Heroku 上运行一个大型应用程序 并且我有某些运行很长时间处理的 celery 任务 并在任务结束时保存结果 每次我在 Heroku 上重新部署时 它都会发送
  • 基于多线程的 RabbitMQ 消费者

    我们有一个 Windows 服务 它监听单个 RabbitMQ 队列并处理消息 我们希望扩展相同的 Windows 服务 以便它可以监听 RabbitMQ 的多个队列并处理消息 不确定使用多线程是否可以实现这一点 因为每个线程都必须侦听 阻
  • RabbitMQ - 如何死信/处理过期队列中的消息?

    我有一个队列x expires放 我遇到的问题是我需要对队列中的消息进行进一步处理IF队列过期 我最初的想法是设置x dead letter exchange在队列中 但是 当队列过期时 消息就会消失而不会进入死信交换 如何处理死信或以其他
  • 面向服务的架构 - AMQP 或 HTTP

    一点背景 非常大的整体 Django 应用程序 所有组件都使用相同的数据库 我们需要分离服务 以便我们可以独立升级系统的某些部分而不影响其余部分 我们使用 RabbitMQ 作为 Celery 的代理 现在我们有两个选择 使用 REST 接
  • 生产者/消费者的不同语言

    我想知道是否可以通过 AMQP 和 RabbitMQ 对生产者和消费者使用不同的语言 例如 Java 代表生产者 python php 代表消费者 或者反之亦然 是的 AMQP 与语言无关 这意味着只要您有可以连接到 AMQP 的客户端sa
  • Rabbit mq - 等待 Mnesia 表时出错

    我已经在 Kubernetes 集群上使用 Helm Chart 安装了 RabbitMQ rabbitmq pod不断重新启动 在检查 pod 日志时 我收到以下错误 2020 02 26 04 42 31 582 warning lt

随机推荐