20240711每日消息队列-------------MQ消息的积压的折磨

目标

解决MQ消息的积压

背景

菜馆系统-----------
系统读取消息,处理业务逻辑,持久化订单和菜品数据,然后将其显示在菜品管理客户端上。
在这里插入图片描述
最初我们的用户基数很小,上线后的一段时间内,MQ消息通信还算顺利。
随着用户规模的扩大,每个商家每天都会产生大量的订单数据,每个订单都包含多个菜品。这导致我们的菜肴管理系统的数据量显着增加。
某一天,商家投诉,称用户下单后平板上的菜品列表出现延迟。
几分钟后厨房才看到菜品。

这能行?

很明显出现这样的菜品展示延迟肯定和Kafka有关,所以我们先从排查Kafka开始。
正如预期的那样,有一个 message backlog 。
通常,消息积压的原因有:

  • MQ 使用者已关闭。
  • MQ 生产者生成消息的速率超过 MQ 消费者消费消息的速率。

我们检查了监控系统,发现我们的MQ消费服务运行正常,没有任何异常。
剩下的原因可能是MQ消费者的消息处理速度变慢了。
接下来我查看了菜品管理表,只有几十万条记录。

首先定位处理MQ日志比较慢的地方:
在代码中添加了一些日志来打印出MQ消费者中各个关键点所花费的时间。
确实有两个地方延迟有点高:
1、有一段代码在for循环中,一条一条的查询数据库。
2、有一段代码执行多条件数据查询。

解决循环查询

对于在for循环中一一查询数据库的代码,我使用参数集合将其更改为 batch query 。
原代码如下:

public List<User> queryUser(List<User> searchList) {if (CollectionUtils.isEmpty(searchList)) {return Collections.emptyList();}List<User> result = Lists.newArrayList();searchList.forEach(user -> result.add(userMapper.getUserById(user.getId())));return result;
}

改进一下:

public List<User> queryUser(List<User> searchList) {if (CollectionUtils.isEmpty(searchList)) {return Collections.emptyList();}List<Long> ids = searchList.stream().map(User::getId).collect(Collectors.toList());return userMapper.getUserByIds(ids);
}

很简单的调整,搞一个ids集合,轻松解决挤压问题。

第二次遇到消息积压

这一次,它是零星的,只是偶尔发生,而不是大多数时候发生。
查了一下菜品管理表,现在已经有几百万条记录了
通过监控和DBA每天的慢查询邮件,我注意到了一些异常情况。

我发现有些SQL语句的WHERE条件完全相同,只是参数值不同,导致使用的索引不同。
例如, order_id=123 使用索引 a,而 order_id=124 使用索引 b。
该表查询场景众多,为了满足不同的业务需求,增加了多个复合索引。

MySQL 根据几个因素选择索引:
1、通过数据采样估计要扫描的行数。更多行可能会导致更高的 I/O 操作和更高的 CPU 使用率。
2、是否使用临时表,也会影响查询速度。
3、是否需要排序,因为它会影响查询速度。

考虑到这些因素和其他因素,MySQL 优化器会选择它认为最合适的索引。

MySQL优化器通过采样来估计要扫描的行数,这涉及到选择一些数据页进行统计估计,从而引入一些误差。

由于MVCC设计,存在多个版本的数据页。例如,删除的数据可能在其他事务中仍然可见,因此索引并未真正删除。这可能会导致统计数据不准确并影响优化器的决策。
这些因素都会导致MySQL在执行SQL语句时出现 错误索引
为了解决MySQL选择错误索引的问题,我们使用 FORCE INDEX 关键字强制SQL查询使用索引a。

FORCE INDEX

force index() 方法强制使用这个索引

第三次遇到消息积压

半年后的某一天,检查监控系统,发现Kafka消息再次积压。
检查了MySQL索引,发现使用了正确的索引,但数据查询仍然很慢。
检查菜品管理表,短短六个月内就增长到了 3000 万条记录。

通常,当单个表包含太多数据时,查询和写入性能都会下降。
这次查询缓慢的原因是数据量太大。

大数据表,解决这个问题,我们需要:
1、实施数据库和表分区
2、备份历史数据

但是我们的体量和预算不支持分库分表

因此,我们决定备份历史数据。
经过与产品经理和DBA讨论,我们决定菜品管理表只保留最近30天的数据,而早于该时间的数据将移至 historical table 。
经过这样的优化,菜品管理表在30天内只积累了几百万条记录,对性能的影响很小。

第四次遇到消息积压

又又又,没错,来了
年后的一个下午,当我查看公司邮件时,发现大量关于Kafka消息积压的监控警报邮件。
下午,这个时间点很奇怪。。。

经过上面的排查都没问题。
我询问订单团队当天下午是否发布了新版本或执行了任何特定功能。因为我们的菜品管理系统是他们的下游系统,跟他们的运营有直接关系。有同事提到,半个小时前,他们做了一个作业,批量更新了几万个订单的状态。更改订单状态会自动发送 MQ 消息。
这导致他们的程序在很短的时间内生成了大量的MQ消息。
我们的 MQ 使用者无法足够快地处理这些消息,导致消息积压。
我们检查了Kafka消息积压情况,发现有几十万条消息在排队。

查看Kafka消息积压情况

https://www.cnblogs.com/lanbojini/p/17314699.html

快速提高MQ消费者的处理速度

我们考虑了两种解决方案:
1、增加分区数量。
2、使用线程池来处理消息。

然而,由于消息已经积压在现有分区中,因此添加新分区并没有多大帮助。
因此,我们决定重构代码以使用 thread pool 来处理消息。
为了开始消耗积压的消息,我们将线程池的核心线程数和最大线程数增加到 50。
此次调整后,积压的数十万条消息在20分钟左右就得到了处理。
解决这个问题后,我们保留了消息消费的线程池逻辑,将核心线程数设置为 8 ,最大线程数设置为 10 。
这使我们能够临时调整线程计数,以快速解决未来的任何消息积压问题,而不会显着影响用户。

注意:使用线程池消费MQ消息并不是通用的解决方案。它有一些缺点,例如潜在的消息排序问题以及导致服务器 CPU 使用率飙升的风险。另外,如果在多线程环境下调用第三方接口,可能会导致第三方服务过载而崩溃。

结语

MQ积压,没有完美的解决方案,只有最适合当前业务场景的解决方案。fuck everythimg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/376831.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s(五)---名称空间

五、名称空间 名称空间是k8s划分不同工作空间的逻辑单位,是k8s资源逻辑隔离的机&#xff0c;。可以给不同的租户&#xff0c;不同的环境、不同的项目创建对应的命名空间。 1、查看名称空间 kubectl get ns kubectl get namespaces 此处展示了四个命名空间 2、管理名称空间 1…

Matlab-Simulink模型保存为图片的方法

有好多种办法将模型保存为图片&#xff0c;这里直接说经常用的 而且贴到Word文档中清晰、操作简单。 simulink自带有截图功能&#xff0c;这两种方法都可以保存模型图片。选择后直接就复制到截切板上了。直接去文档中粘贴就完事了。 这两个格式效果不太一样&#xff0c;第一种清…

[Java IO] 文件的概念与相关操作

一 概念 什么是文件&#xff1f; 文件就是保存数据的地方。 二 文件流 文件在程序中是以流的形式来操作的。 流——数据在数据源&#xff08;文件&#xff09;和程序&#xff08;内存&#xff09;之间经历的路径。 输入流&#xff1a;数据从数据源&#xff08;文件&#…

算法学习day12(动态规划)

一、不同的二叉搜索树 二叉搜索树的性质&#xff1a;父节点比左边的孩子节点都大&#xff1b;比右边的孩子节点都小&#xff1b; 由图片可知&#xff0c;dp[3]是可以由dp[2]和dp[1]得出来的。(二叉搜索树的种类和根节点的val有关) 当val为1时&#xff0c;左边是一定没有节点的…

React18+Redux+antd 项目实战 JS

React18Reduxantd 项目实战 js Ant Design插件官网 Axios官网 (可配置请求拦截器和响应拦截器) JavaScript官网 Echarts官网 一、项目前期准备 1.创建新项目 hotel-manager npx create-react-app hotel-manager2.安装依赖 //安装路由 npm i react-router-domnpm i aixos /…

系统架构师考点--系统安全

大家好。今天我来总结一下系统安全相关的考点&#xff0c;这类考点每年都会考到&#xff0c;一般是在上午场客观题&#xff0c;占2-4分。 一、信息安全基础知识 信息安全包括5个基本要素&#xff1a;机密性、完整性、可用性、可控性与可审查性 (1)机密性&#xff1a;确保信息…

【机器学习理论基础】回归模型定义和分类

定义 回归分析是研究自变量与因变量之间数量变化关系的一种分析方法&#xff0c;它主要是通过因变量 Y Y Y与影响它的自变量 X i X_i Xi​ 之间的回归模型&#xff0c;衡量自变量 X i X_i Xi​ 对因变量 Y Y Y 的影响能力的&#xff0c;进而可以用来预测因变量Y的发展趋势。…

基于Python/MATLAB长时间序列遥感数据处理及在全球变化、植被物候提取、植被变绿与生态系统固碳分析、生物量估算与趋势分析应用

植被是陆地生态系统中最重要的组分之一&#xff0c;也是对气候变化最敏感的组分&#xff0c;其在全球变化过程中起着重要作用&#xff0c;能够指示自然环境中的大气、水、土壤等成分的变化&#xff0c;其年际和季节性变化可以作为地球气候变化的重要指标。此外&#xff0c;由于…

Python3极简教程(一小时学完)下

目录 PEP8 代码风格指南 知识点 介绍 愚蠢的一致性就像没脑子的妖怪 代码排版 缩进 制表符还是空格 每行最大长度 空行 源文件编码 导入包 字符串引号 表达式和语句中的空格 不能忍受的情况 其他建议 注释 块注释 行内注释 文档字符串 版本注记 命名约定 …

WPF学习(4) -- 数据模板

一、DataTemplate 在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;DataTemplate 用于定义数据的可视化呈现方式。它允许你自定义如何展示数据对象&#xff0c;从而实现更灵活和丰富的用户界面。DataTemplate 通常用于控件&#xff08;如ListBox、…

鸿蒙语言基础类库:【@ohos.util (util工具函数)】

util工具函数 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。开发前请熟悉鸿蒙开发指导文档&#xff1a;gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md点击或者复制转到。 该模块…

Wikijs 部署教程

以下是一个 Wikijs 部署的简单教程&#xff0c;涵盖了使用 Docker 和直接安装两种方式&#xff1a; 方法一&#xff1a; 使用 Docker (推荐) Docker 是一个方便快捷的方式来部署 Wikijs&#xff0c;它可以避免许多手动配置步骤。 安装 Docker: 按照 https://docs.docker.com/…

jvm 07 GC算法,内存池

01 垃圾判断算法 1.1引用计数算法 最简单的垃圾判断算法。在对象中添加一个属性用于标记对象被引用的次数&#xff0c;每多一个其他对象引用&#xff0c;计数1&#xff0c; 当引用失效时&#xff0c;计数-1&#xff0c;如果计数0&#xff0c;表示没有其他对象引用&#xff0c;…

TensorBoard ,PIL 和 OpenCV 在深度学习中的应用

重要工具介绍 TensorBoard&#xff1a; 是一个TensorFlow提供的强大工具&#xff0c;用于可视化和理解深度学习模型的训练过程和结果。下面我将介绍TensorBoard的相关知识和使用方法。 TensorBoard 简介 TensorBoard是TensorFlow提供的一个可视化工具&#xff0c;用于&#x…

代理模式(大话设计模式)C/C++版本

代理模式 C #include <iostream> using namespace std;class Subject // Subject 定义了RealSubject和Proxy的共用接口..这样就在任何使用RealSubject的地方都可以使用Proxy { public:virtual void func(){cout << "Subject" << endl;} };class R…

Leetcode3200. 三角形的最大高度

Every day a Leetcode 题目来源&#xff1a;3200. 三角形的最大高度 解法1&#xff1a;模拟 枚举第一行是红色还是蓝色&#xff0c;再按题意模拟即可。 代码&#xff1a; /** lc appleetcode.cn id3200 langcpp** [3200] 三角形的最大高度*/// lc codestart class Solutio…

《Linux系统编程篇》认识在linux上的文件 ——基础篇

前言 Linux系统编程的文件操作如同掌握了一把魔法钥匙&#xff0c;打开了无尽可能性的大门。在这个世界中&#xff0c;你需要了解文件描述符、文件权限、文件路径等基础知识&#xff0c;就像探险家需要了解地图和指南针一样。而了解这些基础知识&#xff0c;就像学会了魔法咒语…

【Python】数据分析-Matplotlib绘图

数据分析 Jupyter Notebook Jupyter Notebook: 一款用于编程、文档、笔记和展示的软件。 启动命令&#xff1a; jupyter notebookMatplotlib 设置中文格式&#xff1a;plt.rcParams[font.sans-serif] [KaiTi] # 查看本地所有字体 import matplotlib.font_manager a sorted…

Hologres+Flink企业级实时数仓核心能力介绍

讲师&#xff1a;骆撷冬 Hologres PD 随着业务发展&#xff0c;业务对于时效性的要求在逐渐提升。各种场景都需要实时&#xff0c;例如春晚实时直播大屏、双11 GMV实时大屏、实时个性化推荐等等多种场景&#xff0c;都对数据的时效性有着非常高的要求。随着实时需求的发展&…

MT6816磁编码IC在工控机器人中的应用

在现代工业自动化领域&#xff0c;高精度的位置检测和控制技术对于机器人系统的稳定运行至关重要。MT6816磁编码IC作为一款先进的磁传感器解决方案&#xff0c;以其卓越的性能和稳定性&#xff0c;在工控机器人中得到了广泛的应用。本文将详细探讨MT6816磁编码IC在工控机器人中…