首页 > 其他分享 >消息队列的延时以及过期失效,消息队列消息积压及占满问题解决思路

消息队列的延时以及过期失效,消息队列消息积压及占满问题解决思路

时间:2023-02-07 15:33:06浏览次数:40  
标签:10 消费 积压 队列 数据 消息 延时 consumer

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

几千万条数据在 MQ 里积压了七八个小时,从下午 4 点多,积压到了晚上 11 点多。这个是我们真实遇到过的一个场景,确实是线上故障了,这个时候要不然就是修复 consumer 的问题,让它恢复消费速度,然后傻傻的等待几个小时消费完毕。这个肯定不能在面试的时候说吧。

一个消费者一秒是 1000 条,一秒 3 个消费者是 3000 条,一分钟就是 18 万条。所以如果你积压了几百万到上千万的数据,即使消费者恢复了,也需要大概 1 小时的时间才能恢复过来。

一般这个时候,只能临时紧急扩容了,具体操作步骤和思路如下:

  • 先修复 consumer 的问题,确保其恢复消费速度,然后将现有 consumer 都停掉。
  • 新建一个 topic,partition 是原来的 10 倍,临时建立好原先 10 倍的 queue 数量。
  • 然后写一个临时的分发数据的 consumer 程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的 10 倍数量的 queue。
  • 接着临时征用 10 倍的机器来部署 consumer,每一批 consumer 消费一个临时 queue 的数据。这种做法相当于是临时将 queue 资源和 consumer 资源扩大 10 倍,以正常的 10 倍速度来消费数据。
  • 等快速消费完积压数据之后,得恢复原先部署的架构重新用原先的 consumer 机器来消费消息。

MQ中的消息过期失效了

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

这个情况下,就不是说要增加 consumer 消费积压的消息,因为实际上没啥积压,而是丢了大量的消息。我们可以采取一个方案,就是批量重导,这个我们之前线上也有类似的场景干过。就是大量积压的时候,我们当时就直接丢弃数据了,然后等过了高峰期以后,比如大家一起喝咖啡熬夜到晚上 12 点以后,用户都睡觉了。这个时候我们就开始写程序,将丢失的那批数据,写个临时程序,一点一点的查出来,然后重新灌入 mq 里面去,把白天丢的数据给他补回来。也只能是这样了。

假设 1 万个订单积压在 mq 里面,没有处理,其中 1000 个订单都丢了,你只能手动写程序把那 1000 个订单给查出来,手动发到 mq 里去再补一次。

MQ 都快写满了

如果消息积压在 mq 里,你很长时间都没有处理掉,此时导致 mq 都快写满了,咋办?这个还有别的办法吗?没有,谁让你第一个方案执行的太慢了,你临时写程序,接入数据来消费,消费一个丢弃一个,都不要了,快速消费掉所有的消息。然后走第二个方案,到了晚上再补数据吧。

对于 RocketMQ,官方针对消息积压问题,提供了解决方案。

1. 提高消费并行度

绝大部分消息消费行为都属于 IO 密集型,即可能是操作数据库,或者调用 RPC,这类消费行为的消费速度在于后端数据库或者外系统的吞吐量,通过增加消费并行度,可以提高总的消费吞吐量,但是并行度增加到一定程度,反而会下降。所以,应用必须要设置合理的并行度。 如下有几种修改消费并行度的方法:

同一个 ConsumerGroup 下,通过增加 Consumer 实例数量来提高并行度(需要注意的是超过订阅队列数的 Consumer 实例无效)。可以通过加机器,或者在已有机器启动多个进程的方式。 提高单个 Consumer 的消费并行线程,通过修改参数 consumeThreadMin、consumeThreadMax 实现。

2. 批量方式消费

某些业务流程如果支持批量方式消费,则可以很大程度上提高消费吞吐量,例如订单扣款类应用,一次处理一个订单耗时 1 s,一次处理 10 个订单可能也只耗时 2 s,这样即可大幅度提高消费的吞吐量,通过设置 consumer 的 consumeMessageBatchMaxSize 返个参数,默认是 1,即一次只消费一条消息,例如设置为 N,那么每次消费的消息数小于等于 N。

3. 跳过非重要消息

发生消息堆积时,如果消费速度一直追不上发送速度,如果业务对数据要求不高的话,可以选择丢弃不重要的消息。例如,当某个队列的消息数堆积到 100000 条以上,则尝试丢弃部分或全部消息,这样就可以快速追上发送消息的速度。

4. 优化每条消息消费过程

举例如下,某条消息的消费过程如下:

  • 根据消息从 DB 查询【数据 1】
  • 根据消息从 DB 查询【数据 2】
  • 复杂的业务计算
  • 向 DB 插入【数据 3】
  • 向 DB 插入【数据 4】

这条消息的消费过程中有 4 次与 DB 的 交互,如果按照每次 5ms 计算,那么总共耗时 20ms,假设业务计算耗时 5ms,那么总过耗时 25ms,所以如果能把 4 次 DB 交互优化为 2 次,那么总耗时就可以优化到 15ms,即总体性能提高了 40%。所以应用如果对时延敏感的话,可以把 DB 部署在 SSD 硬盘,相比于 SCSI 磁盘,前者的 RT 会小很多。

标签:10,消费,积压,队列,数据,消息,延时,consumer
From: https://www.cnblogs.com/songyunjie/p/17098618.html

相关文章

  • 消息队列部署选择
    部署是单机还是集群呢?你们高可用是怎么保证的呢?如果有人问到你MQ的知识,高可用是必问的。上一讲提到,MQ会导致系统可用性降低。所以只要你用了MQ,接下来问的一些要点......
  • (转)go语言-golang基础-queue队列和stack堆栈
    原文:https://www.cnblogs.com/malukang/p/12708850.html1.queue队列队列(queue),是一种FIFO(FirstInFirstOut)先进先出的线性表。通常用数据或者链表来实现队列。队......
  • 实现功能:点击button显示一条消息
    JS单独格式文件:Ajax//npmiexpress安装express//引入constexpress=require('express')//创建应用对象constapp=express();//创建路由app.get('/server',(request......
  • 子线程网络图片查看器和Handler消息处理器
    步骤: 1.页面3.获取http对象的连接4.获取图片Bitmap5.显示页面6.权限注意:如果在子线程中显示图片的话CalledFromWrongThreadException:Onlytheoriginalthreadthatcr......
  • SpringBoot中自定义消息转化器
    场景1.SpringBoot自动配置了消息转化器。2.自定义消息转化器,只需要在类中添加消息转化器的@Bean,就会被SpringBoot自动加入到容器中。实现新建Controllerpackagecom.exampl......
  • PLC利用函数块连接MQTT订阅消息(一)
    在亿佰特介绍了西门子PLC如何通过函数块连接MQTT服务器和发布消息,本文为大家介绍如何通过函数与函数块实现MQTT云消息的订阅,直接切入重点。一、飞燕物联网平台配置这里......
  • PLC利用函数块连接MQTT订阅消息(一)
    在亿佰特介绍了西门子PLC如何通过函数块连接MQTT服务器和发布消息,本文为大家介绍如何通过函数与函数块实现MQTT云消息的订阅,直接切入重点。一、飞燕物联网平台配置这里的配......
  • 没有终结点在侦听可以接受消息的http://192.168.9.31:5289/services/EBService
      原因:我方银行账号启用了支持网银,但未正确配置银企互联,需要取消,如下图: ......
  • ROS多消息同步与多消息回调
    0.存在的问题多传感器数据融合的时候,由于各个传感器采集数据的频率的不同,例如odom50Hz、Imu100Hz、camera25Hz,需要将传感器数据进行时间同步后才能进行融合。这时就需要......
  • 王道视频-数据结构-笔记3:栈和队列
    文章目录0笔记说明1栈1.1栈的定义1.2栈的基本操作描述1.3顺序栈1.3.1顺序栈的基本操作1.3.1.1初始化1.3.1.1.1方式11.3.1.1.2方式21.3.1.2判空1.3.1.2.1方式11.3......