CPU使用率--上篇

CPU使用率

CPU使用率是衡量计算机CPU资源利用程度的指标,表示CPU在一段时间内执行计算任务的占用情况。它可以帮助我们了解系统的负载情况,优化程序性能,以及监控系统的健康状况。

CPU使用率通常以百分比表示,表示CPU在某个时间段内用于执行计算任务的时间占总时间的比例。例如,如果CPU使用率为50%,则表示CPU有一半的时间用于执行计算任务,另一半的时间处于空闲状态。

CPU使用率可以分为以下几种类型:

  1. 用户CPU使用率(User CPU Usage):表示CPU用于执行用户进程的时间占总时间的比例。这部分时间主要用于执行应用程序的代码。
  2. 系统CPU使用率(System CPU Usage):表示CPU用于执行内核进程的时间占总时间的比例。这部分时间主要用于执行操作系统的代码,例如处理中断、调度进程等。
  3. 空闲CPU使用率(Idle CPU Usage):表示CPU处于空闲状态的时间占总时间的比例。这部分时间表示CPU没有执行任何计算任务。
  4. 等待CPU使用率(Wait CPU Usage):表示CPU等待I/O操作完成的时间占总时间的比例。这部分时间主要用于等待外部设备的响应,例如硬盘读写操作。

当涉及到虚拟化环境时,CPU使用率可以进一步细分为以下几种类型:

  1. 虚拟机CPU使用率(Virtual Machine CPU Usage):表示虚拟机实例在宿主机上使用CPU的时间占总时间的比例。这个指标可以帮助管理员了解虚拟机的负载情况,以及宿主机上的资源分配情况。
  2. 宿主机CPU使用率(Host CPU Usage):表示宿主机上所有虚拟机实例使用CPU的时间占总时间的比例。它可以帮助管理员了解宿主机的负载情况,以及宿主机上各个虚拟机实例的资源占用情况。
  3. 多核CPU的每个核心的使用率(Per-Core CPU Usage):表示多核CPU中每个核心使用CPU的时间占总时间的比例。这个指标可以帮助管理员了解每个核心的负载情况,以及平衡负载和优化资源分配。

监控和优化CPU使用率对于系统性能的管理和调优非常重要。通过监控CPU使用率,我们可以了解系统的负载情况,及时发现和解决性能瓶颈,提高系统的响应能力和稳定性。优化CPU使用率可以通过合理调整程序的运行方式、优化算法、增加硬件资源等方式来实现


时间片轮转调度

在Linux操作系统中,为了实现多任务的同时运行,CPU的时间被划分为很短的时间片,并通过调度器轮流分配给各个任务使用。这种机制称为时间片轮转调度

为了维护CPU的时间,Linux定义了一个节拍率(HZ),它表示每秒钟发生的时钟中断次数。在内核中,节拍率以常量的形式定义,通常为100或者1000。这意味着,在每个时间片的时间内,CPU会被中断100或者1000次,然后调度器会根据优先级和调度策略来决定下一个要运行的任务。

为了跟踪和记录系统的时间,Linux使用了一个全局变量Jiffies。Jiffies表示自系统启动以来的节拍数,每次发生时间中断,Jiffies的值就会加1。通过Jiffies的值,我们可以了解系统的运行时间、任务的执行时间以及系统的负载情况。

Jiffies的值可以用于多种用途,例如计算任务执行的时间间隔、计算任务的延迟、监控系统的负载等。在内核中,还有一些其他的时间相关的变量,例如Hertz(每秒钟的节拍数)和Ticks(每个节拍的时钟周期数),它们与Jiffies之间有一定的关系。


系统的节拍率

系统的节拍率(HZ)是指每秒钟发生的时钟中断的次数。它是一个内核配置参数,用于控制操作系统的时间分片和调度机制。

在Linux系统中,HZ的值通常为100或者1000。这意味着每秒钟会发生100或者1000次时钟中断,CPU的时间会被划分为100或者1000个时间片。较高的HZ值意味着时间片更短,任务可以更频繁地切换,提供更细粒度的多任务处理能力,但也会增加系统的开销。

HZ的值会影响到系统的响应性能和负载。较低的HZ值可以降低系统的开销,但可能导致任务切换的粒度较大,影响响应时间。较高的HZ值可以提高系统的响应性能,但会增加系统的开销,尤其在多核系统中。

HZ的值通常在内核编译时进行配置,可以根据系统的需求进行调整。在一般情况下,100或者1000的HZ值已经能够满足大多数应用的需求。对于实时性要求较高的系统,可能需要使用更高的HZ值。

需要注意的是,HZ的值只是一个粗略的配置参数,实际的时间片长度还会受到其他因素的影响,如调度器的算法、任务的优先级等。因此,HZ的值并不是唯一决定系统性能的因素,还需要综合考虑其他因素来进行调优。

如何Jiffies的配置?

  1. 查看内核配置文件:可以通过查看内核配置文件来获取HZ的值。在大多数Linux系统中,内核配置文件通常位于 /usr/src/linux/.config 或者 /boot/config-<kernel-version>。使用文本编辑器打开该文件,在文件中搜索 CONFIG_HZ 或者 CONFIG_HZ_100 或者 CONFIG_HZ_1000,可以找到相应的配置项及其值。
  2. 使用命令行工具:可以使用命令行工具如 cat 或者 grep 来查看系统的配置。打开终端,执行以下命令:
cat /boot/config-$(uname -r) | grep CONFIG_HZ

3.使用 sysctl 命令:sysctl 命令可以用于查看和修改内核参数。执行以下命令:

`sysctl kernel.hz`

4.使用命令行工具:grep

grep 'CONFIG_HZ=' /boot/config-$(uname -r)

5.使用命令行工具:cat /proc/stat | grep ^cpu

#第一列表示的是 CPU 编号,如 cpu0、cpu1 ,而第一行没有编号的 cpu ,表示的是所有 CPU 的累加。其他列则表示不同场景下 CPU 的累加节拍数,它的单位是 USER_HZ,也就是 10 ms(1/100 秒),所以这其实就是不同场景下的 CPU 时间。
cat /proc/stat | grep ^cpu
cpu  120293394 3081 151643776 3993922169 982323 0 6953642 0 0 0
cpu0 15337709 315 19229800 497255021 124961 0 2155989 0 0 0
cpu1 15310499 534 18911637 498751734 141388 0 1167279 0 0 0
cpu2 13870964 291 18403000 500932383 72833 0 996443 0 0 0
cpu3 15102995 378 18909404 499664537 133971 0 601589 0 0 0
cpu4 15223218 401 18931852 499523709 133828 0 541091 0 0 0
cpu5 15256105 466 19017328 499440478 128006 0 513003 0 0 0
cpu6 14987088 298 19062648 499391574 128285 0 492705 0 0 0
cpu7 15204813 394 19178104 498962729 119046 0 485539 0 0 0
参数 解释
cpu 所有CPU核心的总体统计信息 (第一行表示的是所有 CPU 的累加)
cpuN 单个CPU核心的统计信息,其中N是核心的编号
user CPU核心在用户空间运行的时间 (意,它不包括下面的 nice 时间,但包括了 guest 时间)
nice CPU核心在低优先级用户空间运行的时间 (nice 可取值范围是 -20 到 19,数值越大,优先级反而越低)
system CPU核心在内核空间运行的时间
idle CPU核心处于空闲状态的时间
iowait CPU核心等待I/O操作的时间
irq CPU核心处理硬件中断的时间
softirq CPU核心处理软件中断的时间
steal CPU核心被虚拟化环境中的其他任务“偷取”的时间
guest CPU核心运行虚拟化环境中的客户机操作系统的时间
guest_nice CPU核心运行低优先级的虚拟化环境中的客户机操作系统的时间

\(CPU使用率 = 1-\frac{空闲时间}{总CPU时间}\)

这个cpu 使用率是开机以来的累计cpu使用率没有参考价值

\(平均CPU使用率 = 1-\frac{空闲时间_{new}-空闲时间_{old}}{总CPU时间_{new}-总CPU时间_{old}}\)

这个平均CPU使用率才是我们想要的
性能分析工具给出 的都是间隔一段时间的平均 CPU 使用率,所以要注意间隔时间的设置

常见工具平均cpu使用率的时间间隔:

工具 默认CPU使用率时间间隔
top 3秒
mpstat 1秒
sar 1秒
perf 可通过参数自定义
vmstat 1秒
jstat 可通过参数自定义
pidstat 1秒

CPU使用率工具:

$ perf  top
Samples: 1M of event 'cpu-clock', 4000 Hz, Event count (approx.): 11954321649 lost: 0/0 drop: 0/0                                                                 
Overhead  Shared Object                                                            Symbol                                                                         
  15.49%  [kernel]                                                                 [k] ___bpf_prog_run
   8.54%  [kernel]                                                                 [k] _raw_spin_unlock_irqrestore
   6.71%  [kernel]                                                                 [k] __softirqentry_text_start
   3.80%  [kernel]                                                                 [k] finish_task_switch
   2.13%  [kernel]                                                                 [k] do_syscall_64
   1.37%  perf                                                                     [.] rb_next
   1.33%  libc-2.17.so                                                             [.] __strcmp_sse42
   1.32%  libc.so.6                                                                [.] 0x00000000000fcda0
   1.02%  [kernel]                                                                 [k] __audit_syscall_exit
参数 解释
Samples 采样数,即在指定时间间隔内收集到的性能采样数。
Percent 采样数在总采样数中的百分比。
Symbol 采样所在的符号,通常是函数名或代码地址。
Dso 动态共享对象,即包含符号的共享库文件名。
Symbol Name 符号的名称,通常是函数名。
Children 符号的子符号数目。
Self 符号自身的采样数和百分比。
Command 正在运行的进程或线程的命令名称。
$ perf record # 按 Ctrl+C 终止采样
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.452 MB perf.data (6093 samples) ]

$ perf report # 展示类似于 perf top 的报告

top命令简介:

操作指令 功能
h 显示帮助信息,包括可用的操作指令和其功能。
k 发送信号给选定的进程。你需要输入进程的 PID,并选择要发送的信号类型。
q 退出 top 命令。
r 修改进程的优先级。你需要输入进程的 PID,并选择新的优先级。
s 改变刷新间隔时间。你可以输入一个新的刷新间隔时间(以秒为单位)。
1 切换到全局视图模式,显示每个 CPU 核心的详细信息。
l 切换显示平均负载信息。
t 切换显示任务和线程信息。
m 切换显示内存信息。
c 切换显示命令名称而不是进程名称。
f 添加或删除要显示的字段。你可以选择要显示的字段并进行排序。
o 更改排序字段。你可以选择一个新的排序字段来重新排序进程列表。
? 显示当前可用的操作指令和其功能。
#按下数字 1 ,切换到每个 CPU 的使用率
top - 13:50:23 up 62 days, 15:57,  2 users,  load average: 0.52, 0.61, 0.63
Tasks: 342 total,   1 running, 245 sleeping,   0 stopped,   0 zombie
%Cpu0  :  4.0 us,  2.0 sy,  0.0 ni, 93.6 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu1  :  3.4 us,  1.7 sy,  0.0 ni, 94.6 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu2  :  2.7 us,  2.0 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu3  :  2.7 us,  1.7 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu4  :  2.3 us,  2.0 sy,  0.0 ni, 95.3 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
%Cpu5  :  4.0 us,  2.0 sy,  0.0 ni, 94.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu6  :  4.0 us, 17.7 sy,  0.0 ni, 78.3 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu7  :  3.0 us,  1.3 sy,  0.0 ni, 95.6 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem : 16401496 total,  1068232 free, 10275732 used,  5057532 buff/cache
KiB Swap:  4063228 total,  3937020 free,   126208 used.  5721332 avail Mem


   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                     
 75084 1200      20   0   57252  18276   8356 S  17.3  0.1  19:30.37 x11vnc                                                                                      
 70650 root      20   0 4397232 137816  55348 S   3.7  0.8   5:04.84 dockerd                                                                                     
 70981 1001      20   0 8227208 618148  18216 S   2.7  3.8   7:09.88 java                                                                                        
 76018 root      20   0 1220276  59360  34468 S   2.0  0.4   4:20.41 containerd                                                                                  
 70809 root      20   0 1605108   9504   2832 S   1.3  0.1   2:17.61 docker-proxy                                                                                
     1 root      20   0   44016   5916   4096 S   1.0  0.0   1141:05 systemd

pidstat命令简介:

# pidstat 版本查看
pidstat -V
sysstat version 12.7.5
(C) Sebastien Godard (sysstat <at> orange.fr)
$ pidstat 1 5
Average:      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
Average:        0         1    0.20    1.00    0.00    0.00    1.20     -  systemd
Average:        0        10    0.00    0.40    0.00    0.00    0.40     -  rcu_sched
Average:        0      1664    4.58    5.58    0.00    0.00   10.16     -  minio
Average:        0     19907    0.00    0.20    0.00    0.00    0.20     -  kworker/6:2-events_power_efficient
Average:        0     42065    0.40    0.00    0.00    0.00    0.40     -  mongod
Average:        0     69169    0.40    0.00    0.00    0.00    0.40     -  node
Average:        0     69176    0.40    0.20    0.00    0.00    0.60     -  node
Average:        0     69586    0.00    0.20    0.00    0.00    0.20     -  node
Average:        0     69587    0.00    0.20    0.00    0.00    0.20     -  node
参数 解释
Average: 表示这是多次采样的平均值。
UID 进程所属的用户标识符。
PID 进程的标识符。
%usr 用户空间 CPU 使用率。
%system 内核空间 CPU 使用率。
%guest 虚拟机 CPU 使用率。
%wait 等待 CPU 的百分比。
%CPU 总 CPU 使用率。
CPU 执行进程的 CPU 核心编号。
Command 进程的命令名称。

perf top 命令简介:

#pef  -g 开启调用关系分析,-p 指定的进程号 70981  perf top -g -p 70981
Samples: 7K of event 'cpu-clock', 4000 Hz, Event count (approx.): 816541832 lost: 0/0 drop: 0/0                                                                   
  Children      Self  Shared Object       Symbol                                                                                                                  
-   31.73%     0.40%  [kernel]            [k] do_syscall_64                                                                                                      
   - 3.23% do_syscall_64                                                                                                                                         
+    9.01%     0.22%  [kernel]            [k] __x64_sys_futex                                                                                                    
+    8.64%     0.26%  [kernel]            [k] do_futex                                                                                                           
+    7.53%     7.53%  [kernel]            [k] _raw_spin_unlock_irqrestore                                                                                        
+    6.87%     0.01%  [kernel]            [k] do_iter_write                                                                                                      
+    6.66%     0.01%  [kernel]            [k] vfs_writev                                                                                                         
+    6.51%     0.04%  [kernel]            [k] do_iter_readv_writev                                                                                               
+    6.17%     0.06%  [kernel]            [k] tcp_sendmsg_locked                                                                                                 
+    6.07%     0.01%  [kernel]            [k] do_writev                                                                                                          
+    5.91%     0.01%  [kernel]            [k] inet_sendmsg                                                                                                       
+    5.69%     0.06%  [kernel]            [k] tcp_write_xmit                                                                                                     
+    5.47%     0.08%  [kernel]            [k] __tcp_transmit_skb                                                                                                 
+    5.25%     0.00%  [kernel]            [k] ip_queue_xmit
#再按下回车键展开do_syscall_64 的调用关系,你会发现,调用关系最终到了
参数 解释
Samples 采样数,即在指定时间间隔内收集到的性能采样数。
Percent 采样数在总采样数中的百分比。
Symbol 采样所在的符号,通常是函数名或代码地址。
Dso 动态共享对象,即包含符号的共享库文件名。
Symbol Name 符号的名称,通常是函数名。
Children 符号的子符号数目。
Self 符号自身的采样数和百分比。
Command 正在运行的进程或线程的命令名称。

归纳:

  • 用户 CPU 和 Nice CPU高,说明用户态进程占用了较多的CPU,所以应该着重排查进程的 性能问题。
  • 系统 CPU 高,说明内核态占用了较多的 CPU,所以应该着重排查内核线程或者系统调用的性能问题。
  • I/O 等待 CPU 高,说明等待 I/O 的时间比较长,所以应该着重排查系统存储是不是出现了I/O问题。
  • 软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的 CPU,所以应该着重排查 内核中的中断服务程序。
posted @ 2024-02-01 14:46  Emars  阅读(38)  评论(0编辑  收藏  举报