242023.03

运维工具箱 | Linux下如何正确理解CPU使用率?

2023.03.24


DBA小伙伴们运维中是否有过以下烦恼:



1)业务压力很小,但CPU利用率很高;

2)CPU利用率很高,但us(用户空间)利用率低,sy(内核空间)利用率高;

3)CPU利用率高,用尽已知手段排查都无明显效果;

4)面试中被问到的CPU指标含义,无从答起;

5)CPU的各种指标傻傻分不清楚。







工欲善其事,必先利其器。

为了解决上面的问题,我们必须先要了解一下CPU的工作原理,请看下文:



01 什么是CPU使用率?

CPU使用率是单位时间内CPU使用情况的统计,以百分比的方式展示;
 
02如何理解CPU使用率?

Linux是多任务操作系统,会将每个CPU的时间划分成多个很短的时间片,通过内核调度器轮流分配给每个任务使用,Linux通过事先定义的节拍率(HZ)触发时间中断,来维护CPU时间;


03 如何查看CPU的信息?

Linux通过/proc 虚拟文件系统,向用户空间提供了系统内部状态,而/proc/stat提供的就是系统的CPU和任务统计信息。


只保留各个CPU的数据(单位是USER_HZ,10ms(1/100秒))

root-shell> cat /proc/stat|grep ^cpu

cpu 30459469 151 10913958 1322100984 116229 0 2921430 0 0 0

cpu0 214567 0 36786 10389003 334 0 13560 0 0 0

cpu1 216457 0 37424 10414216 251 0 14410 0 0 0

cpu2 217712 0 38434 10413229 177 0 14313 0 0 0

cpu3 214963 0 37932 10416431 254 0 14275 0 0 0

cpu4 215524 0 37006 10416844 252 0 14021 0 0 0

cpu5 214058 0 36704 10418440 297 0 14211 0 0 0

cpu6 214388 0 36772 10417621 237 0 14335 0 0 0

.....



信息解读:




04 如何计算CPU的使用率?

CPU使用率 = 除了空闲时间外的其他时间占总CPU时间的百分比

理论计算公式:CPU使用率 = 1 - 空闲时间 / 总CPU时间

实际计算公式:平均CPU使用率 = 1 - (空闲时间new - 空闲时间old) / (总CPU时间new - 总CPU时间old)



▲ 为什么要按时间计算公式算呢?

因为/proc/stat的节拍数是累加值,所以需要计算两次的差值(执行top命令也是定期更新的,默认是3s更新一次)。



▲ 为什么ps命令和op命令查看到的某个进程的CPU使用率会不一致?

性能分析工具给出的都是间隔一段时间的平均CPU使用率,不同的工具采用的时间间隔不同,会导致输出的结果不同,top默认3s时间间隔,ps则是进程的整个生命周期。



05 如何查看CPU使用率?

1、使用top命令查看CPU使用率

2、使用ps查看CPU使用率



1、使用top命令查看CPU使用率



默认每3秒刷新一次

shell> top

top - 22:15:33 up 1 day, 10:33, 1 user, load average: 23.38, 20.91, 14.41

//启动了1天10个半小时,一个同时在线用户,一分钟负载是23.38,五分钟是20.91,十分钟负载是14.41



Tasks: 1220 total, 1 running, 590 sleeping, 0 stopped, 0 zombie

//有1220个工作任务,正在运行的有1个,590个休眠的,没有被终止的任务,没有僵尸进程


%Cpu(s): 0.0 us, 0.2 sy, 0.0 ni, 99.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

//us:用户空间占用CPU百分比 sy:内核空间占用CPU百分比 ni:用户进程空间内改变过优先级的进程占用CPU百分比 id:空闲CPU百分比 wa:等待io输入输出的CPU时间百分比 hi:硬中断(调用系统的中断程序进行中断,例如程序异常退出等)si:软中断(多线程或多进程下切换时内核态和用户态的一个切换,需要和寄存器、程序计数器交互)st:系统运行虚拟机时被其他虚拟机占用的CPU时间



KiB Mem : 53542118+total, 43122425+free, 99037824 used, 5159104 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 39243321+avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

35384 root 20 0 118976 8640 3712 R 11.8 0.0 0:00.04 top

//PID:进程ID USER:应用名称 PR: 进程优先级,越小越优先 NI:nice值 VIRT:虚拟内存 RES:真实内存(不包含swap out量) SHR:共享内存 S:进程状态{S:sleep状态等待资源,D: 不可中断状态,R:运行状态,T:stop状态,Z:僵尸进程} %CPU:占用CPU的百分比 %MEM:占用内存的百分比 %TIME+:进程运行时间 COMMAND:进程运行命令



1 root 20 0 166912 16896 2624 S 0.0 0.0 3:22.69 systemd

2 root 20 0 0 0 0 S 0.0 0.0 0:00.51 kthreadd





2、使用ps查看CPU使用率



shell> ps -aux|grep pid

USER PID %CPU %MEM VSZ RSS TTY STAT TIME COMMAND

greatdb 94009 3.8 5.8 35479552 31212864 ? Sl 2021 711:24 /greatdb/app/greatdb-1.0.0/bin/greatdb

//USER: 该程序属于哪个用户 PID:该应用程序的PID %CPU:程序占用的CPU资源百分比 %MEM:占用物理内存百分比 VSZ:占用虚拟内存 RSS:占用物理内存量 TTY:在哪个终端运行 STAT 当前状态{R\S\T\Z}