消息队列的消息积压解决办法
Posted __奋斗的卡卡
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了消息队列的消息积压解决办法相关的知识,希望对你有一定的参考价值。
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
数量(新建一个topic
,partition
是原来的10
倍)。
3、然后写一个临时分发消息的consumer
程序,这个程序部署上去消费积压的消息,消费之后不做耗时处理,直接均匀轮询写入临时建好分10
数量的queue
里面。
4、紧接着征用10
倍的机器来部署consumer
,每一批consumer
消费一个临时queue
的消息。
5、这种做法相当于临时将queue
资源和consumer
资源扩大10
倍,以正常速度的10
倍来消费消息。
6、等快速消费完了之后,恢复原来的部署架构,重新用原来的consumer
机器来消费消息。
1.2.2 消息设置了过期时间,过期就丢了怎么办
1.2.2.1 场景
假设你用的是rabbitmq
,rabbitmq
是可以设置过期时间的,就是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
的压力,然后走第二种方案,在晚上夜深人静时去手动查询重导丢失的这部分数据。
以上是关于消息队列的消息积压解决办法的主要内容,如果未能解决你的问题,请参考以下文章