1. mpstat的基本用法:
mpstat的全称为Multiprocessor Statistics,是一款常用的多核CPU性能分析工具,用来实时查询每个CPU的性能指标,以及所有CPU的平均指标。它是Linux性能工具集sysstat中的一个工具
mpstat [-P {|ALL}] [internal [count]]
参数解释:
- -P: 指定要监控哪个CPU,范围是[0 ~ n-1], ALL表示监控所有CPU都监控
- internal: 相邻两次采样的间隔时间
- count: 采样次数。
第一部分:输出首先显示了所有 CPU 的合计指标,然后显示了每个 CPU 各项的指标。
第二部分:在结尾处显示所有 CPU 的平均值。
各列的含义:
%user: 表示用户态所使用 CPU 的百分比。
%nice: 表示使用 nice 命令对进程进行降级时 CPU 的百分比。
%sys: 表示内核进程使用的 CPU 百分比。
%iowait: 表示等待进行 I/O 所使用的 CPU 时间百分比。
%irq: 表示用于处理系统中断的 CPU 百分比。
%soft: 表示用于软件中断的 CPU 百分比。
%steal:虚拟机强制CPU等待的时间百分比。
%guest: 虚拟机占用CPU时间的百分比。
%idle: CPU 的空闲时间的百分比。
2. 高频问题案例
2.1 理解CPU负载
mpstat主要用在当系统变慢,如ssh过去输入命令特别卡,平均负载增大时,我们想判断到底是CPU的使用率增大了,还是IO压力增大的情况。
当系统变慢,我们第一反应是用top或uptime来了解系统的负载情况。
1 2 |
|
load average理解
后面数字是过去1分钟、5分钟、15分钟的平均负载。
2.2 平均负载理解:
不是CPU的使用率,和CPU的使用率没有直接关系。它指的是单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。
所谓的可运行状态,就是用ps命令看到的R状态,它指的是正在使用CPU和正在等待CPU的进程。
所谓的不可中断状态,就是正处于内核状态关键流程的进程,并且这些流程是不可打断的,比如等待硬件设备I/O响应,也就是ps中看到的D状态的进程。
既然是平均活跃进程数,那么最理想的,就是每个CPU上都刚好运行着一个进程,这样每个CPU都得到了充分的利用。比如当平均负载为2时:
在2个CPU的系统上,意味着每个CPU刚好被占完。
在4个CPU的系统上,意味着每个CPU只占50%。
在1个CPU的系统上,意味着有一半的进程竞争不到CPU。
2.3 平均负载到底多少比较合适呢?
前面我们说到,平均负载最理想等于CPU个数,所以要判断平均负载,就先得知道有几个CPU,用如下命令:
1 |
|
有了这个数据,如果平均负载大于大于CPU个数,说明过载了。
不过,平均负载有三个值,我们改参考哪一个呢?其实我们应该根据这三个值来判断系统负载的趋势。
一般在工作中,当平均负载高于70%时,我们根据系统负载的历史数据,判断变化趋势,来排查问题。
2.4 平均负载和CPU使用率的关系
平均负载不仅包含正在使用CPU的进程,还包括等待CPU和等待IO的进程。而CPU的使用率,是单位时间内CPU的繁忙情况,跟平均负载不一定完全对应,比如:
1,计算密集型进程,会大量使用CPU导致平均负载增高,这时,两者一致。
2,I/O密集型进程,等待I/O导致负载很高,但CPU使用率不一定高。
3,大量等待CPU的进程调度也会导致平均负载增高,此时CPU的使用率也会比较高
3. 动手实战
下面我们来演示,上面说的平均负载高的情况。我采用stress压力测试工具,模拟高计算,高IO的情况,使用uptime查看平均负载,使用mpstat和pidstat工具,找出平均负载高的根源。
3.1 计算密集型
模拟一个CPU使用率为100%的场景:
1 |
|
在第二个终端用uptime查看平均负载的变化情况:
1 2 |
|
在第三个终端使用mpstat查看CPU使用率的变化情况
1 2 3 4 5 |
|
通过uptime可以看到,1分钟的平均负载慢慢的增加到1.00,从第三个终端可以看到,有一个CPU的使用率99.67%了,iowait只有0.00。说明平均负载的增高是由于CPU的使用率高。
那么,到底是哪个进程导致了CPU使用率的增高,可以使用pidstat来查询:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
可以看到是stress进程的CPU使用率都快接近100%了。可以kill -9 杀掉
3.2 I/O密集型
模拟高IO的程序。禁用高速缓存
[root@localhost ~]# hdparm -W0 /dev/sda
int main( void ) {
int fd = open("test.txt", O_RDWR|O_DIRECT|O_CREAT, 0644);
int i;
void *buf = (char*)memalign(4096,1,1);
for (i=0; i<521*1024*1024; i++) {
buf = i%26 + 'a';
write(fd, &buf, 1);
fsync(fd);
}
close(fd);
}
14时46分10秒 all 2.87 0.00 29.41 26.40 1.72 0.57 0.00 0.00 39.02mpstat<br>14时46分05秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
14时46分10秒 0 3.74 0.00 39.12 1.02 4.08 0.00 0.00 0.00 52.04
14时46分10秒 1 2.48 0.00 22.28 45.05 0.00 0.74 0.00 0.00 29.46
可以看到iowait已经是45.05%,说明系统平均负载高是有高IO导致的。