导致消息积压的主要原因在于消费者出了问题,不能正常消费。
这种情况下,首先恢复消费者正常服务,消费者恢复后就可以慢慢消化掉这部分积压。
当消息积压太多时,可能需要大量的时间才能消化完,此时我们考虑临时扩容:
- 首先恢复所有消费者,并停掉所有机器
- 创建全新 topic,partition 是原来的10倍
- 临时开发 Consumer 程序,该程序主要消费积压 MQ,消费逻辑不做耗时处理,直接轮询将积压的 MQ 写入前面新建的十倍的 partition 中
- 临时征用十倍机器来部署 consumer,每一台 consumer 消费其中一个 partition 上的数据。这种做法相当于以原先十倍速度来消费数据
- 所有积压数据消费完毕后,删除新机器,恢复原来的 consumer 机器
对于 RabbitMQ,每个消息实际上是可以设置过期时长的,这种情况下不会积压数据,而是直接丢失。此时尽快恢复 consumer 机器,恢复后找流量较低的时间通过日志恢复部分丢失的数据。
假设 MQ 积压过多,消费端恢复后消费速度小于生产者创建速度,以致于 mq 快写满了怎么办。在这种情况下,建议写新的 Consumer 消费 MQ,消费一个丢弃一个,暂时不处理,首先恢复线上最新的 MQ 能处理,后续找时间补上这部分清掉的 MQ。
RocketMQ 官方提供了以下几种处理消息积压的方法:
- 提高消费并行度:增加 Consumer 数量,充分利用多线程多核,提高处理速度
- 批量消费:某些类型的 MQ 批量处理也可以,通过配置参数批量消费 MQ
- 跳过非重要信息:消息积压太多时,放弃一般或全部消息,保证最新的MQ可以正常处理
- 提高消费效率:优化代码层面,主要优化 sql,提高 sql 处理效率