RabbitMq 性能调优记录

RabbitMq 性能调优记录

要避免流控机制触发

  • 服务端默认配置是当内存使用达到40%,磁盘空闲空间小于50M,即启动内存报警,磁盘报警;报警后服务端触发流控(flowcontrol)机制。
  • 一般地,当发布端发送消息速度快于订阅端消费消息的速度时,队列中堆积了大量的消息,导致报警,就会触发流控机制。
  • 触发流控机制后,RabbitMQ服务端接收发布来的消息会变慢,使得进入队列的消息减少
  • 与此同时RabbitMQ服务端的消息推送也会受到极大的影响,测试发现,服务端推送消息的频率会大幅下降,等待下一次推送的时间,有时等1分钟,有时5分钟,甚至30分钟。
  • 一旦触发流控,将导致RabbitMQ服务端性能恶化,推送消息也会变得非常缓慢;
  • 因此要做好数据设计,使得发送速率和接收速率保持平衡,而不至于引起服务器堆积大量消息,进而引发流控。通过增加服务器集群节点,增加消费者,来避免流控发生,治标不治本,而且成本高。
  • 服务器单节点,单网卡全双工情况下,测试发现发布速度过快,压满发布PC机带宽,对于服务器来说,下行(接收)带宽也会压满,可是上行(转发递送)带宽却出现了明显的下降,似乎有一个争抢。这可能是导致触发流控的原因。

从底层取数据一定要非常及时

订阅端每隔500MS调用一次amqp_consume_message接口函数从socket上获取数据,正常情况下,服务器每次会推送几百条消息,而且推送的频率会比较高;

导致订阅端的本机socket缓冲区会很快存满,导致很多消息无法进行缓存,而被丢掉;

发布消息条数调用amqp_comsume_message间隔(MS)实际接收条数
630500269
695470269
513460269
503450503

消息大小不要超过4MB

  • 客户端与RabbitMQ服务端的最大帧是128K,但消息大小却可支持数MB,这是可能是因为底层做了拆包组包的,目前我还未查看底层代码。
  • 用线程来模拟50个发布者和50个订阅者;
消息包大小由1K到10MB,当包大小达到4.5MB时,服务器的性能出现明显的异常,传输率尤其是每秒订阅消息的数量,出现波动,不稳定;同时有一部分订阅者的TCP连接出现断开的现象。可能是客户端底层或者RabbitMQ服务端在进行拆包,组包的时候,出现了明显的压力,而导致异常的发生。
  • 超过4MB的消息,最好先进行分包

consume时预取参数的大小对consume性能影响很大

具体可参见官方博客

磁盘也可能形成瓶颈

磁盘也可能形成瓶颈,如果单台机器队列很多,确认只在必要时才使用duration(持久化),避免把磁盘跑满;

队列的消息大量累积后

队列的消息大量累积后,发送和消费速度都会受到影响,导致服务进一步恶化,采用的方法是,额外的脚本监控每个队列的消息数,超过限额会执行purge操作,简单粗暴但是有效的保证了服务稳定;

调优

单机限制

由于用线程模拟大量发布者,且是服务器单节点,受客户端主机网卡的限制,发布线程没有速度控制,导致有大量数据发送,服务器带宽下行速率也满负荷,上行带宽却明显低于下行速率,导致服务器内存有大量消息堆积,进而触发RabbitMQ服务器paging操作,才出现了上述不稳定和订阅者断开现象。

对发布端做适当流量控制,断开连接现象不再出现,但每秒消息数仍然不稳定

模式对性能的影响

分析三种模式 direct fanout topic

不同的模式对于新建交换机、新建队列、绑定等操作性能影响不大,

但是在direct模式下明显消息发布的性能比其他模式强很多,并且消息发送到相同队列比发送到不同队列性能稍好

持久化对消息性能的影响

在消息持久化模式下:

发布:13888msg/s 
订阅:15384msg/s

在消息非持久化模式下:

发布:18867msg/s 
订阅:26315msg/s

问题分析/解决方案

问题分析:

可以看到RabbitMQ的内存 占用占用已经使用了7.8G 允许的值为 .6G左右

因为 vm_memory_high_watermark 值设置的是0.4 也就是物理内存的40% ;服务器为16G * 40% = 6.4G

一般在产生的原因是长期的生产者发送速率大于消费者消费速率导致. 触发了RabbitMQ 的流控;

解决方案:

  1. 增加消费者端的消费能力,或者增加消费者(根本解决)
  2. 控制消息产生者端的发送速率(不太现实)
  3. 增加mq的内存(治标不治本)

参数调优

vm_memory_high_watermark:用于配置内存阈值,建议小于0.5,因为Erlang GC在最坏情况下会消耗一倍的内存。

vm_memory_high_watermark_paging_ratio:用于配置paging阈值,该值为1时,直接触发内存满阈值,block生产者。

IO_THREAD_POOL_SIZE:CPU大于或等于16核时,将Erlang异步线程池数目设为100左右,提高文件IO性能。

hipe_compile:开启Erlang HiPE编译选项(相当于Erlang的jit技术),能够提高性能20%-50%。在Erlang R17后HiPE已经相当稳定,RabbitMQ官方也建议开启此选项。

queue_index_embed_msgs_below:RabbitMQ 3.5版本引入了将小消息直接存入队列索引(queue_index)的优化,消息持久化直接在amqqueue进程中处理,不再通过msg_store进程。由于消息在5个内部队列中是有序的,所以不再需要额外的位置索引(msg_store_index)。该优化提高了系统性能10%左右。

queue_index_max_journal_entries:journal文件是queue_index为避免过多磁盘寻址添加的一层缓冲(内存文件)。对于生产消费正常的情况,消息生产和消费的记录在journal文件中一致,则不用再保存;对于无消费者情况,该文件增加了一次多余的IO操作。

最佳线程

  • 生产者使用多线程发送数据到queue三到五个线程性能发送最佳,超过它也不能提高生产的发送速率。
  • 消费者的数据处理,使用二线程接收性能是最佳的,如数据处理程序处理比较复杂的逻辑,建议多开启几个线程进行数据接收。
  • 在发送接收队列中,因为发送的速率总比接收的速率要快,因此考虑在接收端配置比发送端更多的线程,个人认为:接收者线程 = 发送者线程 X 1.5

数据恢复

  • RabbitMq在做数据恢复时,遇到过一次数据恢复不了后就没有办法复现。数据恢复的时间会随着数据量的大小成直线增长。
RabbitMQ是一个开源的企业级消息队列系统,它具有高度可扩展性和可靠性。在进行RabbitMQ性能压测时,我们可以采取以下几个方面的方法来评估其性能: 1. 高并发测试:通过发送大量的消息并进行高并发的消费操作来测试RabbitMQ的并发性能。可以模拟多个客户端同时发送消息,然后观察RabbitMQ在高并发情况下的处理能力和消息吞吐量。 2. 延迟测试:通过发送一条消息并进行消费的时间来评估RabbitMQ的消息延迟性能。可以通过记录消息发送的时间和消费的时间间隔来计算延迟时间,并观察消息延迟在不同负载下的表现。 3. 持久化消息测试:测试RabbitMQ在持久化消息的情况下的性能表现。可以将消息设置为持久化,然后发送大量的消息并进行消费操作,观察消息的持久化能力和系统的稳定性。 4. 高可靠性测试:测试RabbitMQ在节点故障或网络断开的情况下的可靠性表现。可以模拟节点宕机或网络中断的情况,观察RabbitMQ在故障恢复后是否能够正确处理消息并保持系统的可用性。 在进行性能压测时,需要注意以下几个方面: 1. 测试环境的准备:需要构建一个具有一定规模的测试环境,包括多个生产者、消费者和消息队列节点,以模拟真实的生产环境。 2. 压测工具的选择:可以使用一些专业的压测工具,如Apache JMeter等,来模拟高并发的消息发送和消费操作。 3. 参数的调优:可以尝试调整RabbitMQ的参数,如连接池大小、线程池大小等,以获得更好的性能表现。 4. 结果的分析:在进行性能压测后,需要对测试结果进行分析和比较,以评估系统的性能和稳定性,并找出可能存在的性能瓶颈和优化点。 通过以上的测试和分析,可以对RabbitMQ的性能进行全面的评估,并根据实际需求来合理调整配置和优化系统,以提升其性能和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值