首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >优化 - 重构一次Mysql导致服务器的OOM

优化 - 重构一次Mysql导致服务器的OOM

原创
作者头像
stark张宇
发布于 2024-01-13 05:36:32
发布于 2024-01-13 05:36:32
2461
举报
文章被收录于专栏:stark张宇stark张宇

概述

优化了一次前后端处理不当导致的CPU的一次爆机行为,当然,这和服务器的配置低也有着密不可分的关系,简单的逻辑学告诉我们,要找到真正的问题,进行解决,CPU爆机的关键点在于前后端两个方面,下面针对具体的问题,进行分析和解决。

定位问题

看监控的图表,CPU已经达到了100%,但是内存的使用曲线很平缓(也说明内存没有被合理的使用),大概率是代码或者循环中产生的问题,服务器进程处理产生多条阻塞,产生的积压,导致的崩溃。

服务端Join影响了性能

顺着代码分析,找到了影响性能的几个关键点,服务端导致性能慢的关键点在于18w的用户表分别和26w的评估记录表、88w的训练动作表、19w的用户签到表进行Join所产生的进程处理缓慢,下面我们用explan工具分别看一下所在的性能差别。

Mysql主要看到的是type和rows的指标,下面的语句告诉我们是全量(all)扫描了179223条数据,优化到了range级别的349条。

代码语言:shell
AI代码解释
复制
+----+-------------+-------+------+-------------------+---------+---------+----------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys     | key     | key_len | ref      | rows   | Extra                                        |
+----+-------------+-------+------+-------------------+---------+---------+----------+--------+----------------------------------------------+
|  1 | SIMPLE      | u     | ALL  | PRIMARY,origin_id | NULL    | NULL    | NULL     | 179223 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | a     | ref  | user_id           | user_id | 4       | cc.u.uid |      1 | Using where                                  |
+----+-------------+-------+------+-------------------+---------+---------+----------+--------+----------------------------------------------+
    2 rows in set (0.01 sec)
代码语言:shell
AI代码解释
复制
+----+-------------+---------------+-------+---------------+---------+---------+------+------+-----------------------------+
| id | select_type | table         | type  | possible_keys | key     | key_len | ref  | rows | Extra                       |
+----+-------------+---------------+-------+---------------+---------+---------+------+------+-----------------------------+
|  1 | SIMPLE      | cc_assessment | range | user_id       | user_id | 4       | NULL |  349 | Using where; Using filesort |
+----+-------------+---------------+-------+---------------+---------+---------+------+------+-----------------------------+

和上面的问题差不多,都是全量检索了80w+数据,优化后range方式检索了1.2w+条数据。

代码语言:shell
AI代码解释
复制
+----+-------------+-------+--------+-------------------+---------+---------+--------------+--------+-------------+
| id | select_type | table | type   | possible_keys     | key     | key_len | ref          | rows   | Extra       |
+----+-------------+-------+--------+-------------------+---------+---------+--------------+--------+-------------+
|  1 | SIMPLE      | t     | ALL    | user_id           | NULL    | NULL    | NULL         | 881949 | Using where |
|  1 | SIMPLE      | u     | eq_ref | PRIMARY,origin_id | PRIMARY | 4       | cc.t.user_id |      1 | Using where |
+----+-------------+-------+--------+-------------------+---------+---------+--------------+--------+-------------+
代码语言:shell
AI代码解释
复制
+----+-------------+-----------------+-------+---------------+---------+---------+------+-------+-------------+
| id | select_type | table           | type  | possible_keys | key     | key_len | ref  | rows  | Extra       |
+----+-------------+-----------------+-------+---------------+---------+---------+------+-------+-------------+
|  1 | SIMPLE      | cc_train_action | range | user_id       | user_id | 4       | NULL | 12979 | Using where |
+----+-------------+-----------------+-------+---------------+---------+---------+------+-------+-------------+

Mysql以page为基础,采用Be+Tree的结构存储在硬盘中,对硬盘的I/O传输效率非常明显和敏感,一般的CPU爆机可能产生的情况就是代码中的循环和递归使用的不当,还有一种可能的情况就是Mysql的Sql使用的不当导致的。

代码字典式拼接

之前的查询写在了循环里,数据多的时候,Mysql需要进行反复的连接、查询、断开影响性能,这个地方也进行了优化。

代码语言:php
AI代码解释
复制
    $areaList = $this->area_model->get_info(['id' => $areaAllIds], '', '', '', 'id,name');
    $areaNameDict = array_column($areaList, 'name', 'id');
    foreach ($user_infos as $key => $val) {
        //数组拼接
        $user_infos[$key]['province_name'] = isset($areaNameDict[$val['native_province_id']]) ? $areaNameDict[$val['native_province_id']] : '';
    }

大胆使用内存

因为内存的曲线较为平缓,说明内存不是导致问题的关键行为,PHP-FPM的特性在子进程执行结束也会进行释放,所以在进程执行时要保证内存的合理使用,可以一次性的加载数据。

代码语言:php
AI代码解释
复制
ini_set('memory_limit', '1024M');

前段的定时器

Http的每一次请求,服务器都会对应开启一个进程,进行处理和响应,前段的小伙伴使用定时器每分钟进行一次请求,导致的直接结果就是服务器进入了多条等待导致的阻塞,直接到CPU打满。

和前端的小伙伴沟通和协商,30分钟请求一次服务,就变的平稳和丝滑了,至此这个问题告一段落了。

最后

我曾经一度认为不停的学习和钻研技术就能做到技术人中的天花板,就可以所向无敌,还是卖炭翁的一句【我亦无他 唯手熟尔】点醒了我,其实就分熟练和不熟练2种 有2点要纠正自己和分享给朋友们,技术人更高维度是要学会合作、沟通和理解,协商的解决问题,Tcp、Http、Udp都是协议,都是请求和响应的双方达成一致,进行的通信。

当然,要保持良好的学习习惯和修炼技能的纯度,也是必不可少的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

评论
登录后参与评论
1 条评论
热度
最新
学到了,博主嘎嘎棒
学到了,博主嘎嘎棒
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
MySQL Explain 使用分析
MySQL 提供了一个 EXPLAIN 命令, 它可以对 SELECT 语句进行分析, 并输出 SELECT 执行的详细信息, 以供开发人员针对性优化.
喝茶去
2019/12/26
3670
mysql explain用法和结果的含义
table 输出的行所引用的表 type 联接类型。下面给出各种联接类型,按照从最佳类型到最坏类型进行排序:
yaphetsfang
2020/07/30
2.4K0
工作中数据库优化技巧
内容整理于网络 一、EXPLAIN 做MySQL优化,我们要善用 EXPLAIN 查看SQL执行计划。 EXPLAIN 输出格式 EXPLAIN 命令的输出内容大致如下: mysql root@localhost:youdi_auth> explain select * from auth_user\G; ***************************[ 1. row ]*************************** id | 1 select_type |
若与
2018/04/25
8450
工作中数据库优化技巧
一次关于 Mysql 索引优化的思考
执行SQL-1,显示耗时 9.35sec。显然是不乐观的一个值,查看其执行计划(explain):
逆锋起笔
2021/04/07
3670
一次关于 Mysql 索引优化的思考
盘点开发中那些常用的MySQL优化
(1)对于MyISAM存储引擎的表,可以使用:DISABLE KEYS 和 ENABLE KEYS 用来打开或者关闭 MyISAM 表非唯一索引的更新。
全栈程序员站长
2022/07/12
5410
盘点开发中那些常用的MySQL优化
不会看 Explain执行计划,劝你简历别写熟悉 SQL优化
昨天中午在食堂,和部门的技术大牛们坐在一桌吃饭,作为一个卑微技术渣仔默默的吃着饭,听大佬们高谈阔论,研究各种高端技术,我TM也想说话可实在插不上嘴。
程序员小富
2020/05/20
8900
不会看 Explain执行计划,劝你简历别写熟悉 SQL优化
Mysql基础篇--面试sql优化
3.匹配最左前缀匹配,仅仅对索引中最左列进行查询,比如复合索引 col1+col2+col3 ,使用索引的是 col1+col2,col1+col3,col1+col2+col3,不会使用索引的是col2+col3,col2.
小土豆Yuki
2020/06/15
8490
MySQL - order by和 group by 优化初探
脑海中要有这个联合索引在MySQL底层的B+Tree的数据结构 , 索引 排好序的数据结构。
小小工匠
2021/08/17
1.6K0
MySQL中的联合索引、覆盖索引及最左匹配原则
叶老师的GreatSQL社区的这篇文章《3.联合索引、覆盖索引及最左匹配原则|MySQL索引学习》,不仅适用于GreatSQL、MySQL,从原理层,对Oracle等数据库同样是通用的。
bisal
2022/05/13
4.4K0
MySQL中的联合索引、覆盖索引及最左匹配原则
3.联合索引、覆盖索引及最左匹配原则|MySQL索引学习
在数据检索的过程中,经常会有多个列的匹配需求,今天介绍下联合索引的使用以及最左匹配原则的案例。
GreatSQL社区
2022/04/18
1.7K0
Extra(5)—mysql执行计划(五十一)
前面说了有type,simple表示普通查询或者连接查询,primary代表union最左边的select,union result代表union查询的临时表去重,所以union all没有去重功能,subquery代表in的子查询物化表的情况下才会出现,dependent subquery代表相关子查询,dependent union代表相关union查询,还有driverd子查询,from后面的,也需要物化,还有物化后转连接查询,这些都能看到mysql优化器是采用哪种查询方式。
keying
2022/07/26
5740
大数据技术之_29_MySQL 高級面试重点串讲_02
  MySQL 是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,目前属于 Oracle 公司。
黑泽君
2019/06/16
6830
MySQL索引优化分析
为什么你写的sql查询慢?为什么你建的索引常失效?通过本章内容,你将学会MySQL性能下降的原因,索引的简介,索引创建的原则,explain命令的使用,以及explain输出字段的意义。助你了解索引,分析索引,使用索引,从而写出更高性能的sql语句。还在等啥子?卷起袖子就是干! 案例分析 我们先简单了解一下非关系型数据库和关系型数据库的区别。 MongoDB是NoSQL中的一种。NoSQL的全称是Not only SQL,非关系型数据库。它的特点是性能高,扩张性强,模式灵活,在高并发场景表现得尤为突出。但目
Spark学习技巧
2018/06/22
8290
一文看懂如何分析MySQL Explain(2/3)
⑨ range:如果使用索引获取某些范围区间的记录,那么就可能使用到range访问方法,比如:
程序员小强
2019/06/11
1.6K0
mysql执行计划看是否最优
介绍   本篇主要通过汇总网上的大牛的知识,简单介绍一下如何使用mysql的执行计划,并根据执行计划判断如何优化和是否索引最优。   执行计划可显示估计查询语句执行计划,从中可以分析查询的执行情况是否最优,有助于对不使用索引的语句进行优化。EXPLAIN对每个查询返回一行信息,列出了有序的表格,MySQL处理语句的时候读取他们。MySQL解决所有的连接使用嵌套连接方法。这意味读取第一张一行,然后匹配第二张表的所有行,第三张表甚至更多表。当所有的表在处理时,MySQL会输出已经查询出来的列,并且回溯到表继续
用户1217611
2018/03/19
2.2K0
MySQL - 践行索引优化
key_len : 显示了mysql在索引里使用的字节数,通过这个值可以算出具体使用了索引中的哪些列。
小小工匠
2021/08/17
5740
MySQL SQL优化
如果一次性需要插入大批量数据(比如: 几百万的记录),使用insert语句插入性能较低,此时可以使用MySQL数据库提供的load指令进行插入。操作如下:
用户9615083
2022/12/25
2K0
MySQL SQL优化
MySQL 索引管理与执行计划
1.1 索引的介绍   索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。如果想按特定职员的姓来查找他或她,则与在表中搜索所有的行相比,索引有助于更快地获取信
惨绿少年
2017/12/27
2K0
MySQL 索引管理与执行计划
Mysql索引使用案例分析
mysql能够在优化阶段分解查询语句,在执行阶段用不着再访问表或索引。例如:在索引列中选取最小值,可以单独查找索引来完成,不需要在执行时访问表
mingjie
2022/05/12
2.3K0
mysql┃explain 都不会用?怎么优化?
现在的java开发人员越来越多,竞争也越来越激烈,moon在某钩招聘网站上发布了一个岗位需求,不到短短1天就收到20多份简历,大部分都是应届一年两年的,新鲜血液越来越多,我们也要不断的提升自己才能够不被挤下去,大家可以看下各大网站的java岗位3年以上的招聘需求:
moon聊技术
2021/07/28
6990
mysql┃explain 都不会用?怎么优化?
相关推荐
MySQL Explain 使用分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档