消息队列的消息积压解决办法

1.1 概述

其实本质针对的场景,就是说可能你的消费端出了问题,不消费了;或者消费的速度极其慢。接着就坑爹了,就可能出现以下三大问题场景:

1、可能你的消息队列集群的磁盘都快写满了,都没人消费,这个时候怎么办?
2、或者是这整个就积压了几个小时,你这个时候怎么办?
3、或者是你积压的时间太长了,导致比如 RabbitMQ 设置了消息过期时间后就没了怎么办?

所以就这事儿,其实线上挺常见的,一出就是大问题。一般常见于,举个例子,消费端每次消费之后要写 mysql,结果 mysql 挂了,消费端停在那儿了,不动了;或者是消费端出了个什么岔子,导致消费速度极其慢。

关于这个事儿,我们一个一个来梳理吧。

1.2 三大问题场景及解决方案

1.2.1 大量消息在mq里积压了几个小时了还没解决

1.2.1.1 场景

几千万条数据在MQ里积压了七八个小时,从下午4点多,积压到了晚上很晚,10点多,11点多。线上故障了,这个时候要不然就是修复consumer的问题,让他恢复消费速度,然后傻傻的等待几个小时消费完毕。这个肯定不行。一个消费者一秒是1000条,一秒3个消费者是3000条,一分钟是18万条,1000多万条。

所以如果你积压了几百万到上千万的数据,即使消费者恢复了,也需要大概1小时的时间才能恢复过来。

1.2.1.2 解决方案

这种时候只能操作临时扩容,以更快的速度去消费数据了。具体操作步骤和思路如下:

1、先修复consumer的问题,确保其恢复消费速度,然后将现有consumer都停掉。

2、临时建立好原先10倍或者20倍的queue数量(新建一个topicpartition是原来的10倍)。

3、然后写一个临时分发消息的consumer程序,这个程序部署上去消费积压的消息,消费之后不做耗时处理,直接均匀轮询写入临时建好分10数量的queue里面。

4、紧接着征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的消息。

5、这种做法相当于临时将queue资源和consumer资源扩大10倍,以正常速度的10倍来消费消息。

6、等快速消费完了之后,恢复原来的部署架构,重新用原来的consumer机器来消费消息。

在这里插入图片描述

1.2.2 消息设置了过期时间,过期就丢了怎么办

1.2.2.1 场景

假设你用的是rabbitmqrabbitmq是可以设置过期时间的,就是TTL,如果消息在queue中积压超过一定的时间就会被rabbitmq给清理掉,这个数据就没了。那这就是第二个坑了。这就不是说数据会大量积压在mq里,而是大量的数据会直接搞丢。

1.2.2.2 解决方案

这种情况下,实际上没有什么消息挤压,而是丢了大量的消息。所以第一种增加consumer肯定不适用。

这种情况可以采取 “批量重导” 的方案来进行解决。
在流量低峰期(比如夜深人静时),写一个程序,手动去查询丢失的那部分数据,然后将消息重新发送到mq里面,把丢失的数据重新补回来。

1.2.3 积压消息长时间没有处理,mq放不下了怎么办

1.2.3.1 场景

如果走的方式是消息积压在mq里,那么如果你很长时间都没处理掉,此时导致mq都快写满了,咋办?这个还有别的办法吗?

1.2.3.2 解决方案

这个就没有办法了,肯定是第一方案执行太慢,这种时候只好采用 “丢弃+批量重导” 的方式来解决了。

首先,临时写个程序,连接到mq里面消费数据,收到消息之后直接将其丢弃,快速消费掉积压的消息,降低MQ的压力,然后走第二种方案,在晚上夜深人静时去手动查询重导丢失的这部分数据。

猜你喜欢

转载自blog.csdn.net/weixin_42039228/article/details/123528619