平均负载
- 平均负载:单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,和 CPU 使用率并没有直接关系。
- 可运行状态的进程:是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
- 不可中断状态的进程:正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。
怎么判断系统负载高?
举一个例子,加入我们在一个 2core cpu 的机器上看到过去 1 分钟,5 分钟,15 分钟的平均负载是load average: 2.78, 0.40, 6.38
,则说明系统在过去一分钟内有 78% 的超载,过去十分钟有 438% 的超载,但整体负载是在降低的。
一般来说,当平均负载高于 cpu 数量 70% 的时间,建议就要分析系统负载高的问题了。
不过,要判断系统的平均负载,得先知道系统有几个 cpu,可以使用如下命令获取:
grep 'model name' /proc/cpuinfo | wc -l
平均负载与 cpu 使用率的关系
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
如何分析平均负载
工具介绍
yum install stress sysstat -y
# sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能。
- stress: 压测工具,模拟日常高负载的场景。
- mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
- pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
cpu 密集型场景
- 窗口 1
# 模拟两个 cpu 被吃满的场景
stress --cpu 2 --timeout 600
- 窗口 2
# 持续关注平均负载的变化情况
watch -d uptime
08:35:27 up 231 days, 18:13, 5 users, load average: 2.19, 1.36, 0.77
- 窗口 3
# 使用 mpstat 查看 cpu 使用率的变化情况
# -P ALL 表示监控所有cpu,间隔 5s输出一次
mpstat -P ALL 5
...
08:31:54 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
08:31:59 AM all 14.62 0.00 1.45 0.04 0.00 0.24 0.00 0.00 0.00 83.65
08:31:59 AM 0 2.45 0.00 1.22 0.20 0.00 0.00 0.00 0.00 0.00 96.12
08:31:59 AM 1 1.41 0.00 1.20 0.00 0.00 1.41 0.00 0.00 0.00 95.98
08:31:59 AM 2 3.84 0.00 1.41 0.00 0.00 0.61 0.00 0.00 0.00 94.14
08:31:59 AM 3 1.81 0.00 1.41 0.00 0.00 0.80 0.00 0.00 0.00 95.98
08:31:59 AM 4 1.21 0.00 1.21 0.00 0.00 0.20 0.00 0.00 0.00 97.38
08:31:59 AM 5 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
08:31:59 AM 6 3.64 0.00 2.83 0.00 0.00 0.20 0.00 0.00 0.00 93.33
08:31:59 AM 7 3.21 0.00 1.40 0.20 0.00 0.20 0.00 0.00 0.00 94.99
08:31:59 AM 8 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
08:31:59 AM 9 1.80 0.00 0.80 0.00 0.00 0.00 0.00 0.00 0.00 97.39
08:31:59 AM 10 2.43 0.00 1.42 0.00 0.00 0.00 0.00 0.00 0.00 96.15
08:31:59 AM 11 1.81 0.00 2.62 0.00 0.00 0.20 0.00 0.00 0.00 95.37
08:31:59 AM 12 2.23 0.00 2.43 0.00 0.00 0.00 0.00 0.00 0.00 95.34
08:31:59 AM 13 2.01 0.00 1.81 0.00 0.00 0.00 0.00 0.00 0.00 96.18
08:31:59 AM 14 2.62 0.00 1.61 0.00 0.00 0.20 0.00 0.00 0.00 95.56
08:31:59 AM 15 2.21 0.00 1.81 0.20 0.00 0.00 0.00 0.00 0.00 95.78
...
可以看到 cpu5 和 9 使用率达到了 100%。
- 窗口4
# 使用 pidstat 查看
# 间隔5秒后输出一组数据
pidstat -u 5 1
08:32:50 AM UID PID %usr %system %guest %wait %CPU CPU Command
...
Average: 999 2896361 0.20 0.00 0.00 0.00 0.20 - argocd-server
Average: 0 3246750 100.00 0.00 0.00 0.00 100.00 - stress
Average: 0 3246751 100.00 0.00 0.00 0.00 100.00 - stress
Average: 0 3248088 0.00 0.20 0.00 0.00 0.20 - kruise-controll
...
可以看到是 stress占满了 cpu
io密集型场景
# 模拟高 io 场景
stress -i 1 --timeout 600
窗口 2
watch -d uptime
Every 2.0s: uptime VM-167-17-tencentos: Sat Dec 30 06:30:52 2023
06:30:52 up 233 days, 16:08, 5 users, load average: 2.38, 1.33, 1.03
可以看到,通过对 io 进行压测,也会导致系统负载的升高
窗口3
# 显示所有CPU的指标,并在间隔5秒输出一组数据
$ mpstat -P ALL 5 1
13:41:28 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
13:41:33 all 0.21 0.00 12.07 32.67 0.00 0.21 0.00 0.00 0.00 54.84
13:41:33 0 0.43 0.00 29.8 62.3 0.00 0.43 0.00 0.00 0.00 7.94
13:41:33 1 0.00 0.00 0.81 0.20 0.00 0.00 0.00 0.00 0.00 98.99
可以看到,cpu 使用率的升高是由于比较高的 io wait 导致。
窗口 4
pidstat -u 5 1
06:33:57 AM UID PID %usr %system %guest %wait %CPU CPU Command
...
06:34:02 AM 0 3274695 0.00 0.20 0.00 0.00 0.20 7 kworker/7:0-events
06:34:02 AM 0 3279743 0.00 78.04 0.00 0.00 78.04 2 stress
06:34:02 AM 0 3280943 0.00 0.20 0.00 0.00 0.20 5 kworker/5:0-events
...
ok,至此,我们已经找到问题在哪里了
大量进程场景
# 模拟多进程场景,16core 机器模拟 32 进程场景
stress -c 32 --timeout 600
窗口 1
watch -d uptime
Every 2.0s: uptime VM-167-17-tencentos: Sat Dec 30 06:52:53 2023
06:52:53 up 233 days, 16:30, 5 users, load average: 30.82, 6.79, 1.34
可以看到,过去 1 分钟系统已经严重超载
窗口 2
mpstat -P ALL 5 1
06:51:34 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
06:51:39 AM all 99.10 0.00 0.86 0.00 0.00 0.04 0.00 0.00 0.00 0.00
06:51:39 AM 0 99.40 0.00 0.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 1 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 2 99.00 0.00 0.80 0.00 0.00 0.20 0.00 0.00 0.00 0.00
06:51:39 AM 3 97.80 0.00 2.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 4 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 5 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 6 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 7 99.40 0.00 0.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 8 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 9 99.40 0.00 0.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 10 98.20 0.00 1.80 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 11 98.00 0.00 1.80 0.00 0.00 0.20 0.00 0.00 0.00 0.00
06:51:39 AM 12 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 13 99.60 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 0.00
06:51:39 AM 14 98.60 0.00 1.20 0.00 0.00 0.20 0.00 0.00 0.00 0.00
06:51:39 AM 15 98.40 0.00 1.60 0.00 0.00 0.00 0.00 0.00 0.00 0.00
如上所示,16 核的 cpu 也被全部占满了
窗口4
pidstat -u 5 1
06:51:52 AM UID PID %usr %system %guest %wait %CPU CPU Command
...
06:51:57 AM 0 3349072 45.65 0.20 0.00 53.95 45.85 2 stress
06:51:57 AM 0 3349073 51.98 0.00 0.00 47.83 51.98 3 stress
06:51:57 AM 0 3349074 46.25 0.00 0.00 53.16 46.25 7 stress
06:51:57 AM 0 3349075 43.68 0.00 0.00 55.93 43.68 13 stress
06:51:57 AM 0 3349076 49.41 0.20 0.00 50.20 49.60 2 stress
06:51:57 AM 0 3349077 44.47 0.00 0.00 55.14 44.47 12 stress
06:51:57 AM 0 3349078 47.63 0.00 0.00 51.98 47.63 14 stress
06:51:57 AM 0 3349079 44.86 0.00 0.00 54.74 44.86 9 stress
06:51:57 AM 0 3349080 46.44 0.00 0.00 53.16 46.44 13 stress
06:51:57 AM 0 3349081 43.68 0.00 0.00 55.93 43.68 12 stress
06:51:57 AM 0 3349082 55.34 0.20 0.00 44.27 55.53 7 stress
06:51:57 AM 0 3349083 47.43 0.00 0.00 52.17 47.43 14 stress
06:51:57 AM 0 3349084 52.37 0.00 0.00 46.84 52.37 15 stress
06:51:57 AM 0 3349085 52.17 0.00 0.00 47.04 52.17 6 stress
06:51:57 AM 0 3349086 44.07 0.00 0.00 55.34 44.07 10 stress
06:51:57 AM 0 3349087 44.66 0.00 0.00 55.14 44.66 4 stress
06:51:57 AM 0 3349088 41.50 0.00 0.00 57.91 41.50 10 stress
06:51:57 AM 0 3349089 43.08 0.00 0.00 56.52 43.08 5 stress
06:51:57 AM 0 3349090 52.57 0.00 0.00 46.84 52.57 15 stress
06:51:57 AM 0 3349091 56.52 0.00 0.00 43.08 56.52 6 stress
06:51:57 AM 0 3349092 49.21 0.20 0.00 50.40 49.41 1 stress
06:51:57 AM 0 3349093 43.48 0.00 0.00 56.13 43.48 11 stress
06:51:57 AM 0 3349094 40.32 0.00 0.00 59.29 40.32 8 stress
06:51:57 AM 0 3349095 59.09 0.20 0.00 40.32 59.29 3 stress
06:51:57 AM 0 3349096 43.68 0.00 0.00 55.93 43.68 0 stress
06:51:57 AM 0 3349097 51.98 0.00 0.00 47.63 51.98 8 stress
06:51:57 AM 0 3349098 50.20 0.00 0.00 49.41 50.20 13 stress
06:51:57 AM 0 3349099 43.08 0.00 0.00 56.52 43.08 5 stress
06:51:57 AM 0 3349100 53.16 0.20 0.00 46.25 53.36 0 stress
06:51:57 AM 0 3349101 50.20 0.00 0.00 49.21 50.20 1 stress
06:51:57 AM 0 3349102 47.43 0.00 0.00 51.98 47.43 9 stress
06:51:57 AM 0 3349103 46.25 0.00 0.00 53.56 46.25 11 stress
06:51:57 AM 0 3351355 0.00 0.20 0.00 0.40 0.20 10 pidstat
总结
通过上面的分析我们可以看出,单纯的看平均负载我们并不能快速的获取到系统的瓶颈到底在哪里,同时也要考虑到,是 cpu 密集型任务导致的?还是 io 密集型任务导致的?可以在实际遇到的时候结合mpstat
,pidstat
等工具,结合实际情况进行分析。