客户现场遇到mongodb cpu偶发性占用过高问题,配置16c16g,装了mysql,mongo,influxdb,java等应用,观察到mongodb在更新数据的时候很慢,几秒甚至几十秒。
通过vmstat 1 10发现bi很高达到2w,
top展开cpu发现有几个cpu的%wa经常在100%,初步判断硬盘负载很高,
用iostat -x 1 10果然硬盘%util达到100%了
iotop发现mysqld占用大量的io
看mysql的日志,发现有超时查询,加完索引后,系统正常。
回头看mongodb的查询慢、偶发性占用cpu 1600%只是表象,因为mongodb需要往硬盘写数据,这个时候硬盘被mysql占用,导致mongodb线程只能等io,mongodb写硬盘的请求积累,cpu也没释放,故cpu占用率高。
load负载和cpu之间关系:
参考: https://www.cnblogs.com/zhangyjblogs/p/14163576.html
## load average定义[#](https://www.cnblogs.com/zhangyjblogs/p/14163576.html#load-average%E5%AE%9A%E4%B9%89)
平均负载是指单位时间内,系统处于**可运行状态**和**不可中断状态**的平均进程数,也就是**平均活跃进程数**,它和CPU使用率并没有直接关系。
**可运行状态**的进程,是指**正在使用CPU或者正在等待CPU的进程**,也就是我们常用ps命令看到的,处于R状态(Running 或 Runnable)的进程。
**不可中断状态**的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的I/O响应。
比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题。
因此前面自己的理解是错误的,比如1min内的平均负载load average指的是1min内**正在使用CPU进程+正在等待CPU的进程+等待IO的进程**,同理5min、15min也是如此计算。
但是,我们平时是java应用,一个应用开启多个线程,这个就涉及到线程和进程的关系了。
linux内进程就是我们ps -fe 看到的,线程是属于进程的,一个进程至少有一个线程,对于我们java应用来说,一个java进程通常有多个线程。线程又称为Light—Weight Process,cpu处理线程是使用分片法,线程也涉及到使用cpu资源和IO(线程向磁盘读写数据),因此平均负载也简单定义为1min内**正在使用CPU线程+正在等待CPU的线程+等待IO的线程**。