io等待为啥引发cpu过高
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了io等待为啥引发cpu过高相关的知识,希望对你有一定的参考价值。
1. 确定高负载的类型,top命令看负载高是CPU还是IO。 2. mysql 下执行查看当前的连接数与执行的sql 语句。 3. 检查慢查询日志,可能是慢查询引起负载高。 参考技术A 还有董大为什么隐患,CPU够高的放到哥这里行动才能可以看一下他们的电瓶面,或者去勾压器 参考技术B 因为他的一个等待的时间吧,引发了他的一个CPU的等量过高。cpu负载突刺问题排查
参考技术A 通过监控工具巡检自己的服务发现服务cpu load存在周期性变高的现象,如图:机器的cpu核数是4核,最高点明显超过了4,但是cpu使用率没有明显变高,如图:
cpu有突刺的现象是gc时引起的,这里先不做赘述;
那么是什么原因引起的cpu load变高呢???,又该如何解决呢?
一、引起load变高的原因有哪些:
1.磁盘io繁忙,网络io繁忙
2.线程上下文切换频繁
3.cpu繁忙
二、根据上面提出的三个原因去寻找解决方案
由上面三张图对比可以看出负载升高的时候,磁盘io以及网络io并没有任何变化还是保持和之前一样,说明不是io影响的。
使用命令:pidstat -w -p <pid>
由以图可以看出来,每秒自愿上下文切换(voluntary context switches)的次数为0(cswch );
被系统强制调度导致,每秒非自愿上下文切换(non voluntary context switches)的次数(nvcswch)的次数也为0;
说明不是线程频繁切换导致的
从最上面的cpu整体使用率看到并不是很高,那么应该不是cpu繁忙导致的;
继续向下排查,
pidstat查看java线程内详细信息,可发现用户态cpu使用率很高,长时间占用CPU,导致等待线程增多;
结合服务业务发现:
该服务是批量拉去kafka消息,然后使用线程池进行消费,而这个线程池使用的拒绝策略为CallerRunsPolicy,也就是当线程池执行不过来,并且阻塞队列也满的时候就会默认使用主线程来进行处理;
继续排查确认:
1.通过命令top -Hp pid 查看进程下最耗费cpu的线程
2.printf “%x\n” 得到线程的16进制
3.jstack 进程 |grep 线程id 获取线程状态
执行以上步骤的到文件,观察发现,最繁忙的线程就是kafka线程
1、减少一批消息的拉去数量,使当前线程池足够消费;
2、增大线程池数量的核心线程数(这种需要判断当前服务是io密集型还是cpu密集型,此方案选用)
3、更改业务逻辑,减少rpc,尽量减少业务处理,加快消费速度;
以上三种方式可以一起使用,也可以部分使用;
1.先减少批量拉取的消息数,观察load是否有降低;
2.因为我的业务服务是网络io密集型,所以我适当增大了业务线程池的核心线程数;
3.最后再来看业务逻辑层面是否存在优化的空间;
前两步结束后,负载已经降低到正常范围时,最后一步业务逻辑优化可选择性的去做;
以上是关于io等待为啥引发cpu过高的主要内容,如果未能解决你的问题,请参考以下文章
linux 性能优化之路: 什么是平均负载, 如何判断是哪种负载过高(cpu密集, io密集, 大量进程)