一、平均负载
定义:单位时间内,系统中处于可运行状态和不可中断状态的平均进程数。
可运行状态的进程:正在使用cpu或者正在等待cpu的进程,即ps aux命令下STAT处于R状态的进程
不可中断状态的进程:处于内核态关键流程中的进程,且不可被打断,如等待硬件设备IO响应,ps命令D状态的进程
理想状态:每个cpu上都有一个活跃进程,即平均负载数等于cpu数
过载经验值:平均负载高于cpu数量70%的时候
2、查看CPU性能相关命令
1、mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
2、pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
3、stress 是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
4、mpstat 是一个用来分析系统的内存使用情况,也常用来分析 CPU 上下文切换和中断的次数的工具
4、sysbench 是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情况
命令安装包: apt install stress sysstat sysbench 或 yum install stress sysstat sysbench
3、命令示例
# 显示cpu核数:
lscpu
grep 'model name' /proc/cpuinfo | wc -l
# 显示平均负载,# 显示的顺序是最近1分钟、5分钟、15分钟,从此可以看出平均负载的趋势:
uptime
top
watch -d uptime #: -d 会高亮显示变化的区域
# 压测命令,--cpu cpu压测选项,-i io压测选项,-c 进程数压测选项,--timeout 执行时间
stress
# 模拟一个 CPU 使用率 100% 的场景
stress --cpu 1 --timeout 600
# 模拟 I/O 压力,即不停地执行 sync
stress -i 1 --timeout 600
# 模拟 8 个进程:
stress -c 8 --timeout 600
# stress的下一代stress-ng,它支持更丰富的选项
stress-ng -i 1 --hdd 1 --timeout 600(--hdd表示读写临时文件)。
# 多核cpu性能分析工具,-P ALL监视所有cpu
mpstat
# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
mpstat -P ALL 5
# 进程性能分析工具,-u 显示cpu使用指标
pidstat
# 间隔5秒后输出一组数据
pidstat -u 5 1
# 查看进程上下文切换 -w参数表示输出进程切换指标
pidstat -w 5
# 上述命令这个结果中有两列内容是我们的重点关注对象。
一个是 cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数
一个是 nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。
# 每隔1秒输出1组数据(需要 Ctrl+C 才结束)
# -w参数表示输出进程切换指标,而-u参数则表示输出CPU使用指标
pidstat -w -u 1
# 每隔1秒输出一组数据(需要 Ctrl+C 才结束)# -wt 参数表示输出线程的上下文切换指标
pidstat -wt 1
# -d 展示 I/O 统计数据,-p 指定进程号,间隔 1 秒输出 3 组数据
$ pidstat -d -p 4344 1 3
06:38:50 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
06:38:51 0 4344 0.00 0.00 0.00 0 app
06:38:52 0 4344 0.00 0.00 0.00 0 app
06:38:53 0 4344 0.00 0.00 0.00 0 app
kB_rd 表示每秒读的 KB 数
kB_wr 表示每秒写的 KB 数
iodelay 表示 I/O 的延迟(单位是时钟周期)
# 查看系统总体的上下文切换情况
vmstat 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 0 7005360 91564 818900 0 0 0 0 25 33 0 0 100 0 0
# 上述vmstat命令结果需要重点关注对象:
cs(context switch)是每秒上下文切换的次数。
in(interrupt)则是每秒中断的次数。
r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
b(Blocked)则是处于不可中断睡眠状态的进程数。
# 以10个线程运行5分钟的基准测试,模拟多线程切换的问题
sysbench --threads=10 --max-time=300 threads run
# 查看中断使用情况
/proc/interrupts 就是这种通信机制的一部分,提供了一个只读的中断使用情况。
# -d 参数表示高亮显示变化的区域
watch -d cat /proc/interrupts
/proc/softirqs 提供了软中断的运行情况;
/proc/interrupts 提供了硬中断的运行情况。
# 排序后查看
watch -d 'cat /proc/interrupts | sort -nr -k 2 '
# perf 是 Linux 2.6.31 以后内置的性能分析工具。它以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。
perf top
Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399
Overhead Shared Object Symbol
7.28% perf [.] 0x00000000001f78a4
4.72% [kernel] [k] vsnprintf
4.32% [kernel] [k] module_get_kallsym
3.65% [kernel] [k] _raw_spin_unlock_irqrestore
...
输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和事件总数量(Event count)。
再往下看是一个表格式样的数据,
每一行包含四列,分别是:第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
第二列 Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),如内核、进程名、动态链接库名、内核模块名等。
第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动态链接库,而 [k] 则表示内核空间。
最后一列 Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表示。
# perf 第二种常见用法,也就是 perf record 和 perf report。 perf top 虽然实时展示了系统的性能信息,但它的缺点是并不保存数据,也就无法用于离线或者后续的分析。而 perf record 则提供了保存数据的功能,保存后的数据,需要你用 perf report 解析展示。
$ 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的报告
在实际使用中,经常为 perf top 和 perf record 加上 -g 参数,开启调用关系的采样,方便我们根据调用链来分析性能问题。
# -g开启调用关系分析,-p指定进程号
$ perf top -g -p <pid>
$ perf record -ag -- sleep 2;perf report
execsnoop 就是一个专为短时进程设计的工具。它通过 ftrace 实时监控进程的 exec() 行为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结果。
dstat 是一个新的性能工具,它吸收了 vmstat、iostat、ifstat 等几种工具的优点,可以同时观察系统的 CPU、磁盘 I/O、网络以及内存使用情况。
# 间隔1秒输出10组数据
$ dstat 1 10
You did not select any stats, using -cdngy by default.
--total-cpu-usage-- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai stl| read writ| recv send| in out | int csw
0 0 96 4 0|1219k 408k| 0 0 | 0 0 | 42 885
0 0 2 98 0| 34M 0 | 198B 790B| 0 0 | 42 138
0 0 0 100 0| 34M 0 | 66B 342B| 0 0 | 42 135
0 0 84 16 0|5633k 0 | 66B 342B| 0 0 | 52 177
0 3 39 58 0| 22M 0 | 66B 342B| 0 0 | 43 144
0 0 0 100 0| 34M 0 | 200B 450B| 0 0 | 46 147
0 0 2 98 0| 34M 0 | 66B 342B| 0 0 | 45 134
0 0 0 100 0| 34M 0 | 66B 342B| 0 0 | 39 131
0 0 83 17 0|5633k 0 | 66B 342B| 0 0 | 46 168
0 3 39 59 0| 22M 0 | 66B 342B| 0 0 | 37 134
从 dstat 的输出,我们可以看到,每当 iowait 升高(wai)时,磁盘的读请求(read)都会很大。这说明 iowait 的升高跟磁盘的读请求有关,很可能就是磁盘读导致的。
strace 正是最常用的跟踪进程系统调用的工具。所以,我们从 pidstat 的输出中拿到进程的 PID 号,比如 6082,然后在终端中运行 strace 命令,并用 -p 参数指定 PID 号:
$ strace -p 6082
strace: attach: ptrace(PTRACE_SEIZE, 6082): Operation not permitted
sar 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告历史统计数据。
sar 可以用来查看系统的网络收发情况,还有一个好处是,不仅可以观察网络收发的吞吐量(BPS,每秒收发的字节数),还可以观察网络收发的 PPS,即每秒收发的网络帧数。
# -n DEV 表示显示网络收发的报告,间隔1秒输出一组数据
$ sar -n DEV 1
15:03:46 IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s %ifutil
15:03:47 eth0 12607.00 6304.00 664.86 358.11 0.00 0.00 0.00 0.01
15:03:47 docker0 6302.00 12604.00 270.79 664.66 0.00 0.00 0.00 0.00
15:03:47 lo 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
15:03:47 veth9f6bbcd 6302.00 12604.00 356.95 664.66 0.00 0.00 0.00 0.05
第一列:表示报告的时间。
第二列:IFACE 表示网卡。
第三、四列:rxpck/s 和 txpck/s 分别表示每秒接收、发送的网络帧数,也就是 PPS。
第五、六列:rxkB/s 和 txkB/s 分别表示每秒接收、发送的千字节数,也就是 BPS。
hping3 是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙测试等。
# -S参数表示设置TCP协议的SYN(同步序列号),-p表示目的端口为80
# -i u100表示每隔100微秒发送一个网络帧
# 注:如果你在实践过程中现象不明显,可以尝试把100调小,比如调成10甚至1
$ hping3 -S -p 80 -i u100 192.168.0.30
tcpdump 是一个常用的网络抓包工具,常用来分析各种网络问题。
# -i eth0 只抓取eth0网卡,-n不解析协议名和主机名
# tcp port 80表示只抓取tcp协议并且端口号为80的网络帧
$ tcpdump -i eth0 -n tcp port 80
15:11:32.678966 IP 192.168.0.2.18238 > 192.168.0.30.80: Flags [S], seq 458303614, win 512, length 0
...
4、平均负载与cpu使用率的区别
CPU使用率: 单位时间内cpu繁忙情况的统计
情况1: CPU密集型进程,CPU使用率和平均负载基本一致
情况2: IO密集型进程,平均负载升高,CPU使用率不一定升高
情况3: 大量等待CPU的进程调度,平均负载升高,CPU使用率也升高
5、不同类型进程观测指标
1. CPU密集型进程case:
mpstat -P ALL 5: -P ALL表示监控所有CPU,5表示每5秒刷新一次数据,观察是否有某个cpu的%usr会很高,但iowait应很低
pidstat -u 5 1:每5秒输出一组数据,观察哪个进程%cpu很高,但是%wait很低,极有可能就是这个进程导致cpu飚高
2. IO密集型进程case:
mpstat -P ALL 5: 观察是否有某个cpu的%iowait很高,同时%usr也较高
pidstat -u 5 1:观察哪个进程%wait较高,同时%CPU也较高
pidstat -d 5 1:观察哪个进程的kB_rd/s kB_wr/s 的指标较高
3. 大量进程case:
pidstat -u 5 1:观察那些%wait较高的进程是否有很多
6、上下文切换指标分析
1、所谓自愿上下文切换,是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。
2、非自愿上下文切换,则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。
1、自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题
2、非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;
3中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文件来分析具体的中断类型。
7、proc/stat文档中关于CPU指标的每列含义解析
# 只保留各个CPU的数据
$ cat /proc/stat | grep ^cpu
cpu 169335831 1377 89883767 5568673446 371534 0 20558393 0 0 0
cpu0 42054301 375 22250264 1391370045 98188 0 10453569 0 0 0
cpu1 42477043 326 22569771 1393014458 76358 0 5333512 0 0 0
cpu2 42590047 329 22607739 1392607302 99902 0 2837353 0 0 0
cpu3 42214438 346 22455991 1391681639 97085 0 1933957 0 0 0
# 上述结果每列含义说明
user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。
nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。
system(通常缩写为 sys),代表内核态 CPU 时间。
idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。
iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。
irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。
softirq(通常缩写为 si),代表处理软中断的 CPU 时间。
steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。
guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。
guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。
8、CPU使用率指标分析
CPU 使用率是最直观和最常用的系统性能指标,更是我们在排查性能问题时,通常会关注的第一个指标。所以我们更要熟悉它的含义,尤其要弄清楚用户(%user)、Nice(%nice)、系统(%system) 、等待 I/O(%iowait) 、中断(%irq)以及软中断(%softirq)这几种不同 CPU 的使用率。
1、用户 CPU 和 Nice CPU 高,说明用户态进程占用了较多的 CPU,所以应该着重排查进程的性能问题。
2、系统 CPU 高,说明内核态占用了较多的 CPU,所以应该着重排查内核线程或者系统调用的性能问题。
3、I/O 等待 CPU 高,说明等待 I/O 的时间比较长,所以应该着重排查系统存储是不是出现了 I/O 问题。
4、软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的 CPU,所以应该着重排查内核中的中断服务程序。
碰到 CPU 使用率升高的问题,你可以借助 top、pidstat 等工具,确认引发 CPU 性能问题的来源;再使用 perf 等工具,排查出引起性能问题的具体函数。
作者:于浩 创建时间:2022-12-23 17:52
最后编辑:于浩 更新时间:2024-07-18 09:14
最后编辑:于浩 更新时间:2024-07-18 09:14