CPU分析工具
方法论
CPU分析的一般步骤:
- 性能监控指标 工具:通过已有指标或者现成的工具进行初步分析和判断
- 使用USE方法进行进一步分析:U:CPU使用率,S:满载率:E:错误
- 测量分析
- 微基准测试
- 静态性能优化
本文侧重对工具的使用介绍。
基础分析工具
基础分析主要包含以下工具的使用:uptime、vmstat、mpstat、sar、ps、top、pidstat,time/ptime
1. uptime
通常uptime可以用来查看系统负载信息
$ uptime 19:10:52 up 1135 days, 7:37, 1 user, load average: 87.87, 77.49, 66.99
最后三列分别是1分钟、5分钟和15分钟系统的平均负载。如果数字是依次减小的,说明现在系统负载在升高,如果是依次增大的,则说明系统负载在降低。
在Linux系统中load值的计算包含系统中正在运行的进行(RUNNING)、可以运行的进程(RUNABLE)和处于不可中断的进程。
2. vmstat
虚拟内存分析工具第一列输出的是可运行进程数,最后几列输出的是cpu相关指标,可以用来分析cpu相关的问题,该工具可显示CPU正式使用率。
$ vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 58 9 0 856644 44052 88905592 0 0 4214 3852 0 0 61 8 26 5 0 60 7 0 973376 44072 88245416 0 0 324648 333560 265446 247480 62 11 23 3 0 58 5 0 1349060 44068 86577808 0 0 289808 257000 270242 276081 55 18 24 3 0 40 24 0 1573068 44080 84997592 0 0 224756 659252 250767 268095 64 13 17 6 0 120 12 0 1636280 44080 83402944 0 0 307740 283888 249253 253964 56 14 22 8 0 37 14 0 867316 44080 81521136 0 0 454760 298512 275080 294816 51 16 24 10 0 52 11 0 2181236 44260 80656688 0 0 445088 560996 298539 249712 56 12 24 9 0 37 6 0 7423208 44260 81312632 0 0 401356 511956 306425 330183 50 9 33 7 0
跟CPU相关的列分析:
- r:对于Linux系统该字段表示所有的Runnable Running进程,不包含处于D状态的进程,如下图所示
- us:用户态(用户)CPU使用率
- sy:内核态(系统)CPU使用率
- id:CPU空闲率
- wa:CPU等待I/O使用率,当进程阻塞在磁盘IO上时可以用来衡量CPU idle
- st:在虚拟化环境显示被其它租户占用的CPU使用率
3. mpstat
多CPU统计工具,可以统计每个CPU的使用情况
~# mpstat -P ALL 1 Linux 5.4.0-99-generic (ambariserver-wangshuaihua-02.dev.kwaidc.com) 02/26/22 _x86_64_ (8 CPU) 15:11:56 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 15:11:57 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 4 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:11:57 7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
命令输出列说明:
- CPU:逻辑CPU序号,或者是all
- %usr:用户态(用户)CPU使用率,不包含%nice
- %nice:带有nice进程的用户态CPU使用率
- %sys:内核态(系统)CPU使用率
- %iowait:I/O wait
- %irq:硬中断CPU使用率
- %soft:软中断CPU使用率
- %steal:虚拟化环境其它租户CPU使用率
- %guest:客户端虚拟机使用使用率
- %gnice:客户端虚拟机带有nice标记的进程CPU使用率
- %idle:CPU剩余率
需要关注的列是 %usr,%sys和%idle,注意查看每个CPU的使用率,看是否存在CPU使用不均衡或者热点。
mpstat默认只显示CPU的整体使用情况,如下图所示:
~# mpstat 1 Linux 5.4.0-99-generic (ambariserver-wangshuaihua-02.dev.kwaidc.com) 02/26/22 _x86_64_ (8 CPU) 15:14:04 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 15:14:05 all 0.00 0.00 0.12 0.00 0.00 0.00 0.00 0.00 0.00 99.88 15:14:06 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00 15:14:07 all 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
4. sar
sar工具可以用来观测多项系统指标,针对CPU的参数有:
- -P ALL:效果与mpstat -P ALL一样,只是输出的列稍微少一些
- -u:与mpstat默认输出结果一样,系统平均指标
- -q:输出run-queue大小,RUNNABLE RUNNING与vmstat的r列内容一致
初次使用sar工具可能会报错,如果没有sar工具则需要安装,安装后可能还会遇到以下错误
~# sar -P ALL Cannot open /var/log/sysstat/sa26: No such file or directory Please check if data collecting is enabled
解决方法:
~# sar -o 2 3
~# sar -P ALL 1 -u -q Linux 5.4.0-99-generic (ambariserver-wangshuaihua-02.dev.kwaidc.com) 02/26/22 _x86_64_ (8 CPU) 15:27:19 CPU %user %nice %system %iowait %steal %idle 15:27:20 all 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 0 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 1 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 2 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 3 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 4 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 5 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 6 0.00 0.00 0.00 0.00 0.00 100.00 15:27:20 7 0.00 0.00 0.00 0.00 0.00 100.00
5. ps
ps方法是非常常用的工具,可以列出所有进程的相关信息,命令格式有两种:
- BSD格式,参数不带'-'字符
- SVR4测试,参数带'-'字符
BSD格式命令输出如下所示:
~# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 171060 13240 ? Ss Feb15 0:27 /sbin/init root 2 0.0 0.0 0 0 ? S Feb15 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? I< Feb15 0:00 [rcu_gp] root 4 0.0 0.0 0 0 ? I< Feb15 0:00 [rcu_par_gp] root 6 0.0 0.0 0 0 ? I< Feb15 0:00 [kworker/0:0H-kblockd] root 9 0.0 0.0 0 0 ? I< Feb15 0:00 [mm_percpu_wq] root 10 0.0 0.0 0 0 ? S Feb15 0:00 [ksoftirqd/0] root 11 0.0 0.0 0 0 ? I Feb15 8:49 [rcu_sched]
SVR4格式命令输出如下所示:
~# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 Feb15 ? 00:00:27 /sbin/init root 2 0 0 Feb15 ? 00:00:00 [kthreadd] root 3 2 0 Feb15 ? 00:00:00 [rcu_gp] root 4 2 0 Feb15 ? 00:00:00 [rcu_par_gp] root 6 2 0 Feb15 ? 00:00:00 [kworker/0:0H-kblockd] root 9 2 0 Feb15 ? 00:00:00 [mm_percpu_wq] root 10 2 0 Feb15 ? 00:00:00 [ksoftirqd/0] root 11 2 0 Feb15 ? 00:08:49 [rcu_sched] root 12 2 0 Feb15 ? 00:00:06 [migration/0]
从命令的输出结果上面,看起来BSD格式的输出信息更全一些,但是ps命令可以通过-o参数定制输出列。针对CPU的使用情况,我们按照BSD格式的输出来说,需要关注的是%CPU和TIME列:
- %CPU:进程从启动以来的平均CPU使用率
- TIME:进程启动以来总消耗的CPU时间用户态 内核态(usr sys)
6. top
top命令可以以指定的时间间隔实时展示进程的CPU使用情况。
~# top top - 23:46:46 up 1135 days, 12:13, 1 user, load average: 46.75, 60.82, 66.77 Tasks: 1660 total, 2 running, 1657 sleeping, 0 stopped, 1 zombie %Cpu(s): 28.5 us, 2.3 sy, 0.0 ni, 63.9 id, 4.7 wa, 0.0 hi, 0.5 si, 0.0 st KiB Mem : 19780201 total, 606332 free, 70851200 used, 12634449 buff/cache KiB Swap: 0 total, 0 free, 0 used. 12021227 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME COMMAND 46652 yarn 20 0 8807788 3.459g 40876 S 428.9 1.8 7:49.67 java 69808 yarn 20 0 8643232 2.257g 41064 S 412.5 1.2 2:12.97 java 6608 yarn 20 0 9153288 3.615g 54376 S 404.9 1.9 17:39.61 java 8852 yarn 20 0 4104884 1.796g 47476 S 104.9 1.0 4:58.38 java 7359 hdfs 20 0 8616144 5.152g 3900 S 90.1 2.7 424070:32 java 46763 yarn 20 0 10.562g 7.527g 108768 S 66.1 4.0 1:09.90 java 28082 yarn 20 0 5371224 1.766g 34608 S 59.9 0.9 3:20.35 java 8030 yarn 20 0 4093672 1.656g 61588 S 52.0 0.9 5:33.91 java 51830 yarn 20 0 14.877g 0.010t 15560 S 33.2 5.3 64477:55 java
top命令的输出结果中包含了系统整体CPU使用情况(第3行),和每个进程的CPU使用情况。对于每个进程CPU使用情况我们需要关注的是%CPU和TIME列:
- %CPU:两次屏幕刷新期间进程的CPU使用率
- TIME:进程启动以来的总CPU使用时间,单位为秒,比如上面输出的7359号进程已经消耗的CPU时间是424070分32秒
虽然top是一个非常基础的分析工具,但是它对性能的损耗不可小觑,在负载重的机器上表现尤为明显,需要谨慎使用。top对系统性能有较大的影响主要是因为要读取/proc下面所有进程的信息。因为top是对/proc做快照,所以很容易漏掉执行时间比较短的进程。
7. pidstat
pidstat可以用来分析单个进程或线程的CPU使用情况,默认情况下会滚动输出。
# pidstat 1 Linux 3.10.0-693.5.2.el7.x86_64 (bjlt-h10366.sy) 02/27/2022 _x86_64_ (56 CPU) 12:00:34 AM UID PID %usr %system %guest %CPU CPU Command 12:00:35 AM 1107 24628 100.00 4.59 0.00 100.00 51 java 12:00:35 AM 1107 29868 100.00 3.67 0.00 100.00 38 java 12:00:35 AM 1107 37421 100.00 2.75 0.00 100.00 45 java 12:00:35 AM 1107 38523 0.92 0.00 0.00 0.92 38 java 12:00:35 AM 1107 44470 100.00 26.61 0.00 100.00 40 java 12:00:35 AM 1107 48401 100.00 17.43 0.00 100.00 40 java 12:00:35 AM 1107 51584 27.52 2.75 0.00 30.28 29 java 12:00:35 AM 1107 51830 0.00 100.00 0.00 100.00 45 java
CPU分析常用参数:
- -p ALL:显示所有进程或线程CPU使用情况
- -t:显示线程粒度统计
8. time
time有两个版本,一个是shell内建的,另外一个是/usr/bin/下的,这两个有不同的使用效果
shell内建time命令:
两次对同一个文件求MD5值
# time md5sum ambari-agent-2.6.2.0-0.x86_64.rpm 06e883c97b88079b0cc71a763fa2a99e ambari-agent-2.6.2.0-0.x86_64.rpm real 0m0.417s user 0m0.175s sys 0m0.056s # time md5sum ambari-agent-2.6.2.0-0.x86_64.rpm 06e883c97b88079b0cc71a763fa2a99e ambari-agent-2.6.2.0-0.x86_64.rpm real 0m0.242s user 0m0.177s sys 0m0.027s
从结果上可以看出第一次使用了0.417秒,用户态使用了0.175秒,内核态使用了0.056秒,其中有0.186(0.417-0.175-0.056)秒的差距,猜测可能是花等磁盘io上了,第二次计算后时间差值缩小到了0.038秒,估计是这个文件已经通过文件系统缓存到了内存中。
/usr/bin/time使用
# /usr/bin/time -v md5sum ambari-agent-2.6.2.0-0.x86_64.rpm 06e883c97b88079b0cc71a763fa2a99e ambari-agent-2.6.2.0-0.x86_64.rpm Command being timed: "md5sum ambari-agent-2.6.2.0-0.x86_64.rpm" User time (seconds): 0.16 System time (seconds): 0.03 Percent of CPU this job got: 98% Elapsed (wall clock) time (h:mm:ss or m:ss): 0:00.20 Average shared text size (kbytes): 0 Average unshared data size (kbytes): 0 Average stack size (kbytes): 0 Average total size (kbytes): 0 Maximum resident set size (kbytes): 724 Average resident set size (kbytes): 0 Major (requiring I/O) page faults: 0 Minor (reclaiming a frame) page faults: 227 Voluntary context switches: 0 Involuntary context switches: 22 Swaps: 0 File system inputs: 0 File system outputs: 0 Socket messages sent: 0 Socket messages received: 0 Signals delivered: 0 Page size (bytes): 4096 Exit status: 0