MQ消息积压

第一次消息积压

通常情况下,出现消息积压的原因有:

  1. mq消费者挂了。

  2. mq生产者生产消息的速度,大于mq消费者消费消息的速度。

消费者挂了重启消费者

第二点主要mq消费者消费消息的速度变慢了

发现有两个地方耗时比较长:

  1. 有个代码是一个for循环中,一个个查询数据库处理数据的。

  2. 有个多条件查询数据的代码。

将在for循环中一个个查询数据库的代码,改成通过参数集合,批量查询数据。 

多条件查询数据的地方,增加了一个联合索引。

第二次消息积压

当时数据只有几百万,发现偶尔会存在消息积压的情况,通过监控发现了慢sql,发现

有些sql语句,执行的where条件是一模一样的,只有条件后面的参数值不一样,导致该sql语句走的索引不一样。

比如:vin=走了索引a,而vin=124走了索引b

有张表查询的场景有很多,当时为了满足不同业务场景,加了多个联合索引。

MySQL会根据下面几个因素选择索引:

  1. 通过采样数据来估算需要扫描的行数,如果扫描的行数多那可能io次数会更多,对cpu的消耗也更大。

  2. 是否会使用临时表,如果使用临时表也会影响查询速度;

  3. 是否需要排序,如果需要排序则也会影响查询速度。

综合1、2、3以及其它的一些因素,MySql优化器会选出它自己认为最合适的索引。

MySQL优化器是通过采样来预估要扫描的行数的,所谓采样就是选择一些数据页来进行统计预估,这个会有一定的误差。

由于MVCC会有多个版本的数据页,比如删除一些数据,但是这些数据由于还在其它的事务中可能会被看到,索引不是真正的删除,这种情况也会导致统计不准确,从而影响优化器的判断。

上面这两个原因导致MySQL在执行SQL语句时,会选错索引

明明使用索引a的时候,执行效率更高,但实际情况却使用了索引b。

为了解决MySQL选错索引的问题,我们使用了关键字force index,来强制查询sql走索引a。

这样优化之后,这次小范围的消息积压问题被解决了。

第三次消息积压

由于数据库表数据激增,单表的数据太多,无论是查询,还是写入的性能,都会下降。

  1. 做分库分表

  2. 将历史数据备份

只保留最近30天的数据,超过几天的数据写入到历史表中。

这样优化之后,30天只会产生几百万的数据,对性能影响不大。

消息积压的问题被解决了。

第四次消息积压

有时程序在极短的时间内,产生了大量的mq消息。

mq消费者根本无法处理这些消息,所以才会产生消息积压的问题。

要想快速提升mq消费者的处理速度,我们当时想到了两个方案:

  1. 增加partion数量。

  2. 使用线程池处理消息。

但考虑到,当时消息已经积压到几个已有的partion中了,再新增partion意义不大。

使用线程池处理消息

为了开始消费积压的消息,我们将线程池的核心线程最大线程数量调大到了50。

这两个参数是可以动态配置的。

这样调整之后,积压了几十万的mq消息,在20分钟左右被消费完了。

这次突然产生的消息积压问题被解决了。

解决完这次的问题之后,我们还是保留的线程池消费消息的逻辑,将核心线程数调到8,最大线程数调到10

当后面出现消息积压问题,可以及时通过调整线程数量,先临时解决问题,而不会对用户造成太大的影响。

注意:使用线程池消费mq消息不是万能的。该方案也有一些弊端,它有消息顺序的问题,也可能会导致服务器的CPU使用率飙升。此外,如果在多线程中调用了第三方接口,可能会导致该第三方接口的压力太大,而直接挂掉。

总之,MQ的消息积压问题,不是一个简单的问题。

虽说产生的根本原因是:MQ生产者生产消息的速度,大于MQ消费者消费消息的速度,但产生的具体原因有多种。

我们在实际工作中,需要针对不同的业务场景,做不同的优化。

我们需要对MQ队列中的消息积压情况,进行监控和预警,至少能够及时发现问题。

没有最好的方案,只有最合适当前业务场景的方案。

 

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值