前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >遇到了消息堆积,但是问题不大

遇到了消息堆积,但是问题不大

作者头像
Vincent-yuan
发布于 2021-11-04 08:12:21
发布于 2021-11-04 08:12:21
4720
举报
文章被收录于专栏:Vincent-yuanVincent-yuan

这一篇我们要说的话题是消息的堆积处理,其实这个话题还是挺大的,因为消息堆积还是真的很令人头疼的,当堆积的量很大的时候,这真的是个很暴躁的问题,不过这时候真考验大家冷静的处理问题的能力了

我们一起来分析分析有关问题吧

大量的消息堆积在MQ中几个小时还没解决怎么办呢

一般这种比较着急的问题,最好的办法就是临时扩容,用更快的速度来消费数据

1、临时建立一个新的Topic,然后调整queue的数量为原来的10倍或者20倍,根据堆积情况来决定

2、然后写一个临时分发消息的consumer程序,这个程序部署上去消费积压的消息,消费的就是刚刚新建的Topic,消费之后不做耗时的处理,只需要直接均匀的轮询将这些消息轮询的写入到临时创建的queue里面即可

3、然后增加相应倍数的机器来部署真正的consumer消费,注意这里的Topic,然后让这些consumer去真正的消费这些临时的queue里面的消息

不知道大家明白没有,很简单的道理,我给大家举个形象的例子

一个topic堵住了,新建一个topic去进行分流,临时将queue资源和consumer资源扩大10倍,将消息平均分配到这些新增的queue资源和consumer资源上,以正常10倍的速度来消费消息,等到这些堆积的消息消费完了,便可以恢复到原来的部署架构

这种只是用于临时解决一些异常情况导致的消息堆积的处理,如果消息经常出现堵塞的情况,那该考虑一下彻底增强系统的部署架构了

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

在rabbitmq中,可以设置过期时间TTL,和Redis的过期时间一样,如果消息在queue中积压超过一定时间就会被rabbitmq清理掉,这个数据就没了

这样可能会造成大量的数据丢失

这种情况下上面的解决方案就不太合适了,可以采取批量重导的方案来解决,在系统流量比较低的时候,用程序去查询丢失的这部分数据,然后将消息重新发送到MQ中,把丢失的数据重新补回来

这也算是一种补偿任务吧,补偿任务一般是用于对定时跑批的一种补偿

分析下RocketMQ中的消息堆积原因

消息的堆积归根到底就是生产者生产消息的速度和消费者消费的速度不匹配导致的,输入的和消费的速度不统一

或许是突然搞了一波促销,系统业务量暴增,导致生产者发消息暴增,消费速度跟不上

也有可能是消费方出现失败的情况,疯狂重试,也或者就是消费方的消费能力太低了

RocketMQ是按照队列进行消息负载的,如果consumer中的一台机器由于硬件各方面原因导致该机器上的消息队列不能及时处理,就会造成整个消息队列的堆积

RocketMQ分为发布方和订阅方,双方都有负载均衡策略,默认都是采用平均分配,producer消息以轮询方式发送到消息队列queue中,broker将这些的queue再平均分配到属于同一个group id的订阅方集群

  • .如果消费者consumer机器数量和消息队列相等,则消息队列平均分配到每一个consumer上
  • 如果consumer数量大于消息队列数量,则超出消息队列数量的机器没有可以处理的消息队列
  • 若消息队列数量不是consumer的整数倍,则部分consumer会承担跟多的消息队列的消费任务

如果其中一台机器处理变慢,可能是机器硬件、系统、远程 RPC 调用或 Java GC 等原因导致分配至此机器上的 Queue 的消息不能及时处理 消息队列 RocketMQ 版的消息负载是按 Queue 为粒度维护,所以,整个 Queue 上的消息都会堆积

那说一下解决思路吧

我们知道了最根本原因是生产和消费速度不匹配导致的,这种问题要是经常出现,就是系统架构导致,这种需要考虑增加消费方的数量了 如果是搞促销的这种临时情况导致的,这种情况下系统应该会比较快的消化掉,堆积时间不会很快,如果搞促销时间很长,持续高流量时间很长,那没得办法,还是得加机器 经常出现这种消息堆积问题,需要先定位一下消费满的原因,也也可能是代码bug,导致多次重试,如果是bug则处理bug,优化下消费的逻辑 再者就要考虑水平扩容,增加Topic的queue数量和消费者的数量,这两者增加的时候需要考虑两边的平衡,队列数量一定要增加,不然新增加的消费数量者会导致无消息消费的尴尬场面,一个topic中的一个队列只会分配给一个消费者 消费者数量超过队列数量的时候,超出的部分消费者就无消息可以消费了

RocketMQ中消费完的消息去了哪里呢

消息的存储是一直存在于CommitLog文件中的,大家都知道CommitLog是以文件为单位存在的,而且RocketMQ的设计是只允许顺序写,也就意味着所有消息都是顺序的写入到这个文件中的 而每个消息的大小又不是定长的,所以这就决定了消息几乎不可能按照消息为单位进行删除,逻辑极其复杂 消息一旦被消费了之后是不会被立即清除的,还是会存在于CommitLog文件中的,那问题来了,消息未删除,RocketMQ是如何知道哪些消息已经被消费过,哪些还未消费呢 答案就是客户端会维护一个消息的offset,客户端拉取完消息之后,broker会随着响应体返回一个下一次拉取的位置,消费者会更新自己的下一次的pull的位置

CommitLog文件什么时候进行清除

消息存储到该文件之后,也是会被清理的,但是这个清理只会在下面这些条件中,任一条件成立的时候才会批量的删除CommitLog消息文件

  • 消息文件过期(默认72小时),且到达清理时点(默认是凌晨4点),删除过期文件。
  • 消息文件过期(默认72小时),且磁盘空间达到了水位线(默认75%),删除过期文件。
  • 磁盘已经达到必须释放的上限(85%水位线)的时候,则开始批量清理文件(无论是否过期),直到空间充足。

注:若磁盘空间达到危险水位线(默认90%),出于保护自身的目的,broker会拒绝写入服务。

为什么这么设计呢

CommitLog文件默认大小是1GB,在清理的时候属于大文件操作了,IO压力也是有的,这样设计该文件的优点我大概说几个,当然肯定还有些别的

只需要保存一份消息文件:一个消息如果需要被多个消费者组消费,消息只需要保存一份即可,消费进度单独保存,这样比较容易支撑强大的消息存储能力 支持回溯:把消息的消费位置的决定权放在客户端,只要消息还在,就可以消费,所以也就有了RocketMQ支持的回溯消费 像看视频一样,可以把镜头调到前面去,重新看一遍刚刚的视频 支持消息索引服务:RocketMQ中有一个索引文件,消息只要还存在于CommitLog中,就可以被搜索出来,方便排查问题

参考:https://mp.weixin.qq.com/s/darDDxORk7261vJAqg3Tmg

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-11-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
美团字节大数据面试SQL-每分钟最大直播人数
有如下数据记录直播平台主播上播及下播时间,根据该数据计算出平台每分钟最大直播人数。
数据仓库晨曦
2024/05/18
3900
美团字节大数据面试SQL-每分钟最大直播人数
大数据面试SQL048-泳池问题(下)
我们接着上两题继续讨论泳池问题,还是相同的数据。现有一份数据记录了用户进入和离开游泳池的时间,请计算出泳池内的平均人数
数据仓库晨曦
2024/04/11
1300
大数据面试SQL048-泳池问题(下)
客快物流大数据项目(六十四):运单主题
“运单是运输合同的证明,是承运人已经接收货物的收据。一份运单,填写一个托运人、收货人、起运港、到达港。如同一托运人的货物分别属到达港的两个或两个以上收货人,则应分别填制运单。”
Lansonli
2022/03/13
8830
客快物流大数据项目(六十四):运单主题
客快物流大数据项目(六十五):仓库主题
从2005年开始,网购快递每年以倍增的速度增长。重大节日前是快递爆仓发生的时段。如五一节前夕、国庆节前夕、圣诞节前夕、元旦前夕、春节前夕。新兴的光棍节,网购日,2010年“光棍节、圣诞节、元旦”和春节前夕,淘宝网、京东商城等网商集中促销造成部分民营快递企业多次发生爆仓现象。如2011年11月11日世纪光棍节,淘宝网当天交易额33亿,包裹堆积成山,快递公司原有的交通工具和人员,远远无法满足运送这么多包裹的要求,因此造成包裹被堆积在仓库长达十几天。广州市甚至出现同城快件10天不到的情况。
Lansonli
2022/05/12
7860
客快物流大数据项目(六十五):仓库主题
大数据面试SQL047-泳池问题(中)
我们接着上一题大数据面试SQL046-泳池问题(上)继续讨论泳池问题。现有一份数据记录了用户进入和离开游泳池的时间,请找出一天中泳池最多人数持续时长,如有出现多次最高人数,对时间求和
数据仓库晨曦
2024/04/11
1480
大数据面试SQL047-泳池问题(中)
快手大数据面试SQL-用户中两人一定认识的组合数
有某城市网吧上网记录表,包含字段:网吧id,访客id(身份证号),上线时间,下线时间。
数据仓库晨曦
2024/06/17
1230
快手大数据面试SQL-用户中两人一定认识的组合数
最强最全面的大数据SQL面试题和答案(由31位大佬共同协作完成)
本套SQL题的答案是由许多大佬共同贡献,1+1的力量是远远大于2的,有不少题目都采用了非常巧妙的解法,也有不少题目有多种解法。本套大数据SQL题不仅题目丰富多样,答案更是精彩绝伦!
五分钟学大数据
2021/12/27
5.2K0
字节快手大数据面试SQL-最高峰同时直播人数
有如下数据记录直播平台主播上播及下播时间,根据该数据计算出平台最高峰同时直播人数。
数据仓库晨曦
2024/04/30
2280
字节快手大数据面试SQL-最高峰同时直播人数
客快物流大数据项目(二十五):初始化业务数据
chown -R oracle:oinstall /u01/app/oracle/oggdata/orcl
Lansonli
2022/02/08
5630
客快物流大数据项目(二十五):初始化业务数据
客快物流大数据项目(五十一):数据库表分析
​​​​​​​7、客户寄件信息表(tbl_consumer_sender_info)
Lansonli
2022/02/28
1.2K0
客快物流大数据项目(五十一):数据库表分析
Hive学习-数据查询语句
hive> SELECT [ALL | DISTINCT] SELECT_expr, SELECT_expr, ... FROM table_reference
顾翔
2024/09/10
1420
Hive学习-数据查询语句
基于Hadoop生态圈的数据仓库实践 —— 进阶技术(九)
九、退化维度 本节讨论一种称为退化维度的技术。该技术减少维度的数量,简化维度数据仓库模式。简单的模式比复杂的更容易理解,也有更好的查询性能。当一个维度没有数据仓库需要的任何数据时就可以退化此维度,此时需要把退化维度的相关数据迁移到事实表中,然后删除退化的维度。 1. 退化订单维度 本小节说明如何退化订单维度,包括对数据仓库模式和定期装载脚本的修改。使用维度退化技术时你首先要识别数据,分析从来不用的数据列。例如,订单维度的order_number列就可能是这样的一列。但如果用户想看事务的细节,还需要订单号。因此,在退化订单维度前,要把订单号迁移到sales_order_fact表。下图显示了迁移后的模式。
用户1148526
2019/05/25
3840
全网最全Hive近百个函数详解
Apache Hive是一个建立在Apache Hadoop之上的数据仓库软件项目,用于提供数据查询和分析,现支持引擎有MapReduce、Tez、Spark等等。
用户7600169
2022/04/25
1.8K0
美团大数据面试SQL-计算用户首单是即时单的比例
在外卖订单中,有时用户会指定订单的配送时间。现定义:如果用户下单日期与期望配送日期相同则认为是即时单,如果用户下单日期与期望配送时间不同则是预约单。每个用户下单时间最早的一单为用户首单,请计算用户首单中即时单的占比。
数据仓库晨曦
2024/07/25
1750
美团大数据面试SQL-计算用户首单是即时单的比例
面试系列-mysql基础语法
alter table 表名 modify column 列名 新类型 [约束]; 或者
用户4283147
2022/10/27
1.6K0
常见大数据面试SQL-查询每个产品每年总销售额
已知有表如下,记录了每个产品id、产品名称、产品销售开始日期、产品销售结束日期以及产品日均销售金额,请计算出每个产品每年的销售金额
数据仓库晨曦
2024/06/28
2050
常见大数据面试SQL-查询每个产品每年总销售额
2024Mysql And Redis基础与进阶操作系列(7)作者——LJS[含MySQL 聚合、数学、字符创、日期、控制流函数等使用详解;注意点及常见报错问题所对应的解决方法]
聚合函数主要由:count,sum,min,max,avg,这些聚合函数我之前都写过,不再重叙。
盛透侧视攻城狮
2024/10/22
1050
常见大数据面试SQL-各用户最长的连续登录天数-可间断
现有各用户的登录记录表t_login_events如下,表中每行数据表达的信息是一个用户何时登录了平台。现要求统计各用户最长的连续登录天数,间断一天也算作连续,例如:一个用户在1,3,5,6登录,则视为连续6天登录。
数据仓库晨曦
2024/07/12
5590
常见大数据面试SQL-各用户最长的连续登录天数-可间断
(文末有福利)使用collec_list、collect_set函数进行行转列
该函数是非确定性的,因为收集结果的顺序取决于行的顺序,这在经过shuffle之后可能是不确定的。
数据仓库晨曦
2024/08/12
1990
(文末有福利)使用collec_list、collect_set函数进行行转列
腾讯大数据面试SQL-连续登陆超过N天的用户
现有用户登录日志表 t_login_log,包含用户ID(user_id),登录日期(login_date)。数据已经按照用户日期去重,请查出连续登录超过4天的用户ID
数据仓库晨曦
2024/06/27
1630
腾讯大数据面试SQL-连续登陆超过N天的用户
推荐阅读
相关推荐
美团字节大数据面试SQL-每分钟最大直播人数
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档