系统优化-CPU-如何排查CPU使用率到100%

我们如何去查看CPU的使用率呢?CPU使用率中的几个重要指标分别代表什么?

CPU使用率相关的概念介绍

我们多核的CPU为了能“并行”运行我们的程序,我们需要为每个进程分配执行时间,执行时间到了我们会进行一次中断,中断的频率我们定义为hz,其中内核态的中断我们可以设置,一般是100,250,1000hz,表示秒中断多少次,我们的用户态是没法直接控制hz的。用户态则规定为100HZ,也就是10ms。我们查看CPU的指标的单位就是10ms。

我们可以通过查看/proc/cpu/stat来看cpu的指标。

1
2
3
4
5
6
7
8
9
10
cat /proc/cpu/stat|grep ^cpu

cpu 280580 7407 286084 172900810 83602 0 583 0 0 0
cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0
cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0

man /proc/stat
#kernel/system statistics. Varies with architecture. Common entries include:
# The amount of time, measured in units of USER_HZ (1/100ths of a second on most architectures, use sysconf(_SC_CLK_TCK) to obtain the right value), that the system spent in various states:
# Number of processes in runnable state. (Linux 2.5.45 onward.)

其中几个重要指标

  • user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。
  • nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越
  • system(通常缩写为 sys),代表内核态 CPU 时间。
  • idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
  • iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
  • irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
  • softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
  • steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。
  • guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。
  • guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。

    我们还可以通过/proc/$pid/stat看某个进程的cpu使用情况,但是这些都是开机到现在的历史时间。其实是没有参考价值的,我们应该看一段时间内的cpu使用情况,我们一般采用以下2个方法看

top

按1查看每个cpu

1
Cpu(s): 10.2%us,  5.8%sy,  0.0%ni, 83.2%id,  0.0%wa,  0.0%hi,  0.8%si,  0.0%st

pidstat

1
2
3
4
5
6
7
8

pid -u 5 1

Linux 3.10.0-514.16.1.es01.x86_64 (xxxxx.xxx) 04/22/2020 _x86_64_ (40 CPU)

01:58:07 PM PID %usr %system %guest %CPU CPU Command
01:58:12 PM 354 0.00 1.20 0.00 1.20 10 xxxxx
01:58:12 PM 946 0.20 0.40 0.00 0.60 14 java

CPU使用过高怎么办

我们前期可以采用perf,不用gdb的原因是gdb会阻塞进程影响线上应用

1
2
3
4
5
6
7
8
9

$ perf top
Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399
Overhead Shared Object Symbol
7.28% perf [.] 0x00000000001f78a4
4.72% [kernel] [k] vsnprintf
4.32% [kernel] [k] module_get_kallsym
3.65% [kernel] [k] _raw_spin_unlock_irqrestore
...

也可以采用perf record && perf report来进行采样

其中 perf 添加-g可以查看具体的调用链

案例的总结

user+nice过高说明程序的进程可优化
sys过高可能是内核调度服务出问题
iowait过高可能是磁盘io出问题
si+hi过高可能是内核中断出问题