1.CPU使用率

Linux作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运行的错觉。
为了维护CPU时间,Linux通过事先定义的节拍率(内核中表示为HZ),触发时间中断,并使用全局变量Jiffies记录了开机以来的节拍数。每发生一次时间中断,Jiffies的值就加1。
节拍率HZ是内核的可配选项,可以设置为100、250、1000等,不同的系统可能设置不同的数值。
可以在/boot/config文件下查看对应的配置值。

  1. [root@localhost ~]# grep "CONFIG_HZ" /boot/config-3.10.0-1160.15.2.el7.x86_64
  2. # CONFIG_HZ_PERIODIC is not set
  3. # CONFIG_HZ_100 is not set
  4. # CONFIG_HZ_250 is not set
  5. # CONFIG_HZ_300 is not set
  6. CONFIG_HZ_1000=y
  7. CONFIG_HZ=1000
  8. 节拍率设置成了1000,也就是每秒触发1000次时间中断

同时,正因为节拍率是内核选项,所以用户空间程序并不能直接访问。为了方便用户空间程序,内核还提供了一个用户空间节拍率USER_HZ,它总是固定为100,也就是1/100秒。这样,空间用户程序并不需要关心内核中HZ被设置成了多少,因为它看到的总是固定值USER_HZ。
Linux通过/proc虚拟文件系统,向用户空间提供了系统内部状态的信息,而/proc/stat提供的就是系统的CPU和任务统计信息。比方说,如果你只关注CPU的话,可以执行下面的命令:

  1. [root@localhost ~]# cat /proc/stat | grep ^cpu
  2. cpu 874610 53 821410 353430723 148102 0 21072 0 0 0
  3. cpu0 425415 25 444857 176637439 73200 0 6996 0 0 0
  4. cpu1 449194 28 376552 176793284 74901 0 14075 0 0 0
  5. 其中第1列是CPU编号,如CPU0CPU1,而第一行没有编号的CPU,表示的是所有CPU的累加,其他列则表示
  6. 不同场景下CPU的累加节拍数。它的单位事USER_HZ,也就是10ms。所以这就是不同场景下的CPU时间。

CPU使用率的相关指标:

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

而我们通常所说的CPU使用率,就是除了空闲时间外的其他时间占总CPU时间的百分比,用公式来表示就是:
CPU使用率=1-(空闲时间/总CPU时间)
根据这个公式,我们就可以从/proc/stat中的数据,很容易计算出CPU使用率。当然也,也可以用每一个场景的CPU时间,除以总的CPU时间,计算出每个场景的CPU使用率。
但是如果直接使用/proc/stat的数据,算的是开机以来的节拍数累加值,所以直接算出来的,是开机以来的平均CPU使用率,一般没啥价值。
所以,为了计算CPU使用率,性能工具一般都会取间隔一段时间(比如3秒)的两次值,作差后,再计算出这段时间内的平均CPU使用率,即:
平均CPU使用率=1-(空闲时间(new)-空闲时间(old)/ 总CPU时间(new)-总CPU时间(old))
这个公式,就是我们用各种性能工具所看到的CPU使用率的实际计算方法。
现在,我们知道了系统CPU使用率的计算方法,那进程的呢?跟系统的指标类型,Linux也给每个进程提供了运行情况的统计信息,也就是/proc/[pid]/stat。不过,这个文件包含的数据就比较丰富了,总共有52列数据。
当然CPU的使用率不一定就需要从/proc/stat或者/proc/[pid]/stat这两个文件中读取,因为各种各样的性能工具已经帮我们计算好了,不过要注意的是,性能分析工具给出的都是间隔一段时间的平均CPU使用率,所以要注意间隔的设置。特别是用多个工具对比分析时,一定要保证他们用的是相同的间隔。

2. 怎么查看CPU使用率

top:显示了系统总体的CPU和内存使用情况,以及各个进程的资源情况。
ps:则只显示了每个进程的资源使用情况

top的输出格式为:

  1. 默认每3秒刷新一次:
  2. [root@localhost ~]# top
  3. top - 09:33:21 up 21 days, 10:22, 1 user, load average: 0.00, 0.01, 0.05
  4. Tasks: 183 total, 1 running, 182 sleeping, 0 stopped, 0 zombie
  5. %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
  6. %Cpu1 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
  7. KiB Mem : 2027892 total, 201460 free, 504108 used, 1322324 buff/cache
  8. KiB Swap: 2097148 total, 2066428 free, 30720 used. 1286460 avail Mem
  9. PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
  10. 1390 freeswi+ -2 -10 1296352 35700 3660 S 0.7 1.8 194:18.22 freeswitch
  11. 1347 mysql 20 0 1119884 179528 636 S 0.3 8.9 12:07.50 mysqld
  12. 106800 root 20 0 162104 2324 1592 R 0.3 0.1 0:00.03 top
  13. 1 root 20 0 125764 2904 1708 S 0.0 0.1 0:47.51 systemd
  14. 2 root 20 0 0 0 0 S 0.0 0.0 0:00.18 kthreadd
  15. 4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
  16. 6 root 20 0 0 0 0 S 0.0 0.0 0:12.70 ksoftirqd/0
  17. 可使用数字1切换总的CPU使用率和平均每个CPU的使用率
  18. 在空白行之后,是进程的实时信息,每个进程包含一个%CPU列,表示进程的CPU使用率,它是用户态和内核态
  19. CPU使用率的总和,包括进程用户空间使用的CPU,通过系统调用执行的内核空间CPU、以及在就绪队列等待运
  20. 行的CPU。在虚拟化环境中,他还包括了运行虚拟机占用的CPU

到此,可以发现,top并没有细分进程的用户态CPU和内核态CPU。可以使用mpstat命令。

  1. [root@localhost ~]# mpstat -P ALL 5
  2. Linux 3.10.0-1160.15.2.el7.x86_64 (localhost.localdomain) 05/22/2021 _x86_64_ (2 CPU)
  3. 11:35:05 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
  4. 11:35:10 AM all 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 99.90
  5. 11:35:10 AM 0 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.80
  6. 11:35:10 AM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
  7. %usr:用户态CPU使用率
  8. %system:内核态CPU使用率
  9. %guest:运行虚拟机CPU使用率
  10. %CPU:总的CPU使用率
  11. %wait:等待CPU使用率

3.CPU使用率过高怎么办

perf是一款性能分析工具,以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
第一种用法是perf top,它能够实时显示占用CPU时钟最多的函数或者指令,因此可以用来查找热点函数。

  1. [root@localhost ~]# perf top
  2. Samples: 1K of event 'cpu-clock', 4000 Hz, Event count (approx.): 78812852 lost: 0/0 drop: 0/0
  3. Overhead Shared Object Symbol
  4. 28.61% [kernel] [k] _raw_spin_unlock_irqrestore
  5. 9.73% [kernel] [k] clear_page
  6. 6.85% [kernel] [k] finish_task_switch
  7. 6.84% perf [.] __symbols__insert
  8. 3.00% [kernel] [k] __mem_cgroup_commit_charge
  9. 2.57% perf [.] rb_next
  10. 2.47% [kernel] [k] copy_user_generic_unrolle
  11. 输出结果中,第一行中包含3个数据,分别是采样数(samples)、事件类型、