1.CPU使用率
Linux作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运行的错觉。
为了维护CPU时间,Linux通过事先定义的节拍率(内核中表示为HZ),触发时间中断,并使用全局变量Jiffies记录了开机以来的节拍数。每发生一次时间中断,Jiffies的值就加1。
节拍率HZ是内核的可配选项,可以设置为100、250、1000等,不同的系统可能设置不同的数值。
可以在/boot/config文件下查看对应的配置值。
[root@localhost ~]# grep "CONFIG_HZ" /boot/config-3.10.0-1160.15.2.el7.x86_64# CONFIG_HZ_PERIODIC is not set# CONFIG_HZ_100 is not set# CONFIG_HZ_250 is not set# CONFIG_HZ_300 is not setCONFIG_HZ_1000=yCONFIG_HZ=1000节拍率设置成了1000,也就是每秒触发1000次时间中断
同时,正因为节拍率是内核选项,所以用户空间程序并不能直接访问。为了方便用户空间程序,内核还提供了一个用户空间节拍率USER_HZ,它总是固定为100,也就是1/100秒。这样,空间用户程序并不需要关心内核中HZ被设置成了多少,因为它看到的总是固定值USER_HZ。
Linux通过/proc虚拟文件系统,向用户空间提供了系统内部状态的信息,而/proc/stat提供的就是系统的CPU和任务统计信息。比方说,如果你只关注CPU的话,可以执行下面的命令:
[root@localhost ~]# cat /proc/stat | grep ^cpucpu 874610 53 821410 353430723 148102 0 21072 0 0 0cpu0 425415 25 444857 176637439 73200 0 6996 0 0 0cpu1 449194 28 376552 176793284 74901 0 14075 0 0 0其中第1列是CPU编号,如CPU0,CPU1,而第一行没有编号的CPU,表示的是所有CPU的累加,其他列则表示不同场景下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的输出格式为:
默认每3秒刷新一次:[root@localhost ~]# toptop - 09:33:21 up 21 days, 10:22, 1 user, load average: 0.00, 0.01, 0.05Tasks: 183 total, 1 running, 182 sleeping, 0 stopped, 0 zombie%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%Cpu1 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 stKiB Mem : 2027892 total, 201460 free, 504108 used, 1322324 buff/cacheKiB Swap: 2097148 total, 2066428 free, 30720 used. 1286460 avail MemPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND1390 freeswi+ -2 -10 1296352 35700 3660 S 0.7 1.8 194:18.22 freeswitch1347 mysql 20 0 1119884 179528 636 S 0.3 8.9 12:07.50 mysqld106800 root 20 0 162104 2324 1592 R 0.3 0.1 0:00.03 top1 root 20 0 125764 2904 1708 S 0.0 0.1 0:47.51 systemd2 root 20 0 0 0 0 S 0.0 0.0 0:00.18 kthreadd4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H6 root 20 0 0 0 0 S 0.0 0.0 0:12.70 ksoftirqd/0可使用数字1切换总的CPU使用率和平均每个CPU的使用率在空白行之后,是进程的实时信息,每个进程包含一个%CPU列,表示进程的CPU使用率,它是用户态和内核态CPU使用率的总和,包括进程用户空间使用的CPU,通过系统调用执行的内核空间CPU、以及在就绪队列等待运行的CPU。在虚拟化环境中,他还包括了运行虚拟机占用的CPU。
到此,可以发现,top并没有细分进程的用户态CPU和内核态CPU。可以使用mpstat命令。
[root@localhost ~]# mpstat -P ALL 5Linux 3.10.0-1160.15.2.el7.x86_64 (localhost.localdomain) 05/22/2021 _x86_64_ (2 CPU)11:35:05 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle11:35:10 AM all 0.00 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 99.9011:35:10 AM 0 0.00 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 99.8011:35:10 AM 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00%usr:用户态CPU使用率%system:内核态CPU使用率%guest:运行虚拟机CPU使用率%CPU:总的CPU使用率%wait:等待CPU使用率
3.CPU使用率过高怎么办
perf是一款性能分析工具,以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
第一种用法是perf top,它能够实时显示占用CPU时钟最多的函数或者指令,因此可以用来查找热点函数。
[root@localhost ~]# perf topSamples: 1K of event 'cpu-clock', 4000 Hz, Event count (approx.): 78812852 lost: 0/0 drop: 0/0Overhead Shared Object Symbol28.61% [kernel] [k] _raw_spin_unlock_irqrestore9.73% [kernel] [k] clear_page6.85% [kernel] [k] finish_task_switch6.84% perf [.] __symbols__insert3.00% [kernel] [k] __mem_cgroup_commit_charge2.57% perf [.] rb_next2.47% [kernel] [k] copy_user_generic_unrolle输出结果中,第一行中包含3个数据,分别是采样数(samples)、事件类型、
