【1】CPU飙升到200%以上问题汇总

原链接

【1】CPU飙升到200%以上问题汇总

CPU飙升到200%以上是生成中常见的问题

注意:

  1. linux的cpu使用频率是根据cpu个数和核数决定的

  2. top,然后你按一下键盘的1,这就是单个核心的负载,不然是所有核心的负载相加,自然会超过100

所有cpu使用率总和:

top

top # 进入交互界面

接下来按1,查看每个cpu占用

我的云服务器是2核的,因此显示的是有2个cpu

查询结果按照cpu使用率排

shift+P

按照内存占用率排序

shift+M

1 MySQL进程飙升到900%

我们日常在使用MySQL的过程中,或多或少都遇到过CPU突然过高,或者达到200%以上的情况。

  • 数据库执行查询或数据修改操作时,系统需要消耗大量的CPU资源维护从存储系统、内存数据中的一致性。
  • 并发量大并且大量SQL性能低的情况下,比如字段是没有建立索引,则会导致快速CPU飙升,如果还开启了慢日志记录,会导致性能更加恶化。生产上有MYSQL 飙升900% 的恶劣情况。
1.1 定位过程
  1. 使用top命令查看是否是mysqld导致还是其他原因
  2. 如果是mysqld导致,show processlist,查看session情况,确定是否有消耗资源的sql在运行
  3. 找到消耗高的sql,查看执行计划是否准确,index是否缺失,或者是数据量太大导致。
1.2 处理过程
  1. kill掉这些线程(观察cpu使用率是否下降,通常都会下降)
  2. 进行加索引、改SQL、改内存参数

index是否缺失,如果是,则建立索引,也有可能是每个SQL消耗资源并不多,但是突然有大量的session连进导致cpu飙升,这种情况就需要跟应用一起来分析为何连接数会激增,再做出相应的调整,如:限制连接数等。

mysql查看索引 show index from 表名;

  1. 优化的过程,往往不是一步完成的,而是一步一步,执行一项优化措施,再观察,再优化。
1.3 真实案例

之前开发同事编写的SQL语句,就导致过线上CPU过高,MySQL的CPU使用率达到900%+,通过优化最后降低到70%~80%。下面说说个人在这个过程中的排查思路。

首先,我们要对问题定位而不是盲目的开启什么 慢日志,在并发量大并且大量SQL性能低的情况下,开启慢日志无意是将MySQL推向崩溃的边缘。

当时遇到这个情况,分析了当前的数据量、索引情况、缓存使用情况。目测数据量不大,也就几百万条而已。接下来就去定位索引、缓存问题。

  1. 经过询问,发现很多查询都是走MySQL,没有用到缓存。
  2. 既然没有用到缓存,则是大量请求全部查询MySQL导致。通过下面的命令查看:

show processlist;

发现类似很多相同的SQL语句,一直处于query状态中。

select id form user where user_code = 'xxxxx';

初步分析可能是 user_code 字段没有索引导致。接着查询user表的索引情况:

show index form user;

发现这个字段是没有建立索引。增加索引之后,该条SQL查询能够正常执行。

3、没隔一会,又发生大量的请求超时问题。接着进行分析,发现是开启了 慢日志查询。大量的SQL查询语句超过慢日志设置的阀值,于是将慢日志关闭之后,速度瞬间提升。CPU的使用率基本保持在300%左右。但还不是理想状态。

查看是否开启慢日志

show variables like "%slow_query_log%";

拓展:

  1. 慢查询日志,主要用来记录在 MySQL 中执行时间超过指定时间的 SQL 语句。通过慢查询日志,可以查找出哪些语句的执行效率低,以便进行优化。
  2. 慢查询日志,不能随意开启。对于需要大量IO的mysql操作,开启慢查询日志对mysql性能的影响可能远高于理论值,在亿级数据insert场景中,开启慢查询日志后insert数据慢了三倍以上。

4、紧接着将部分实时查询数据的SQL语句,都通过缓存(redis)读写实现。观察一段时间后,基本维持在了70%~80%。

总结:其实本次事故的解决很简单,就是添加索引与缓存结合使用。

  • 不推荐在这种CPU使用过高的情况下进行慢日志的开启。因为大量的请求,如果真是慢日志问题会发生日志磁盘写入,性能贼低。
    直接通过MySQL show processlist命令查看,基本能清晰的定位出部分查询问题严重的SQL语句,在针对该SQL语句进行分析。一般可能就是索引、锁、查询大量字段、大表等问题导致。
  • 再则一定要使用缓存系统,降低对MySQL的查询频次。
    对于内存调优,也是一种解决方案。

2 Java进程飙升到900%

一般来说Java 进程不做大量 CPU 运算,正常情况下,CPU 应该在 100~200% 之间,

但是,一旦高并发场景,要么走到了死循环,要么就是在做大量的 GC, 容易出现这种 CPU 飙升的情况,CPU飙升900%,是完全有可能的。

2.1 定位过程

CPU飙升问题定位的一般步骤是:

  1. top指令查看当前占用CPU较高的进程PID;

top

  1. 查看当前进程消耗资源的线程ID(tid):top -Hp PID

top -Hp PID

  1. 通过print命令将线程PID转为16进制,根据该16进制值去打印的堆栈日志内查询,查看该线程所驻留的方法位置。

printf "%x\n" tid(线程id)

  1. 通过jstack命令,查看栈信息,定位到线程对应的具体代码。

pid:java进程id nid线程id的十六进制

jstack <pid> |grep -A 200 <nid>

  1. 分析代码解决问题。
相关推荐
帅得不敢出门5 小时前
安卓设备adb执行AT指令控制电话卡
android·adb·sim卡·at指令·电话卡
鬼才血脉7 小时前
docker+mysql配置
mysql·adb·docker
CircleMouse14 小时前
MySQL8完全卸载方法-Win10系统
adb
小小哭包14 小时前
MySQL日期时间函数大全
android·adb
ShuQiHere1 天前
【ShuQiHere】️`adb kill-server` 和 `adb start-server` 命令的作用
adb
ShuQiHere2 天前
【ShuQiHere】️ 深入了解 ADB(Android Debug Bridge):您的 Android 开发利器!
android·adb
fighting_sunnyGirl2 天前
mac端mumu模拟器adb识别不了问题
macos·adb
D@.3 天前
如何将MySQL彻底卸载干净
数据库·mysql·adb·方法·彻底删除
CYRUS STUDIO3 天前
adb 远程调试,手动修改 adb 调试授权信息
android·adb·调试
侯卓4 天前
mysql8 window 免安装
adb