CPU使用率
CPU使用率是衡量计算机CPU资源利用程度的指标,表示CPU在一段时间内执行计算任务的占用情况。它可以帮助我们了解系统的负载情况,优化程序性能,以及监控系统的健康状况。
CPU使用率通常以百分比表示,表示CPU在某个时间段内用于执行计算任务的时间占总时间的比例。例如,如果CPU使用率为50%,则表示CPU有一半的时间用于执行计算任务,另一半的时间处于空闲状态。
CPU使用率可以分为以下几种类型:
- 用户CPU使用率(User CPU Usage):表示CPU用于执行用户进程的时间占总时间的比例。这部分时间主要用于执行应用程序的代码。
- 系统CPU使用率(System CPU Usage):表示CPU用于执行内核进程的时间占总时间的比例。这部分时间主要用于执行操作系统的代码,例如处理中断、调度进程等。
- 空闲CPU使用率(Idle CPU Usage):表示CPU处于空闲状态的时间占总时间的比例。这部分时间表示CPU没有执行任何计算任务。
- 等待CPU使用率(Wait CPU Usage):表示CPU等待I/O操作完成的时间占总时间的比例。这部分时间主要用于等待外部设备的响应,例如硬盘读写操作。
当涉及到虚拟化环境时,CPU使用率可以进一步细分为以下几种类型:
- 虚拟机CPU使用率(Virtual Machine CPU Usage):表示虚拟机实例在宿主机上使用CPU的时间占总时间的比例。这个指标可以帮助管理员了解虚拟机的负载情况,以及宿主机上的资源分配情况。
- 宿主机CPU使用率(Host CPU Usage):表示宿主机上所有虚拟机实例使用CPU的时间占总时间的比例。它可以帮助管理员了解宿主机的负载情况,以及宿主机上各个虚拟机实例的资源占用情况。
- 多核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的配置?
- 查看内核配置文件:可以通过查看内核配置文件来获取HZ的值。在大多数Linux系统中,内核配置文件通常位于
/usr/src/linux/.config
或者/boot/config-<kernel-version>
。使用文本编辑器打开该文件,在文件中搜索CONFIG_HZ
或者CONFIG_HZ_100
或者CONFIG_HZ_1000
,可以找到相应的配置项及其值。 - 使用命令行工具:可以使用命令行工具如
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,所以应该着重排查 内核中的中断服务程序。