这篇文章上次修改于 899 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

1 平均负载

当系统变慢时,通常会执行 uptime 或 top

$ uptime
 15:44:12 up 35 days, 18:53, 11 users,  load average: 0.00, 0.01, 0.00

当前系统时间为 15:44:12,系统运行了 35d 18h 53min,正在登录的用户数为 11,过去 1min、5min、15min 的平均负载分别为 0.00,0.01,0.00

平均负载:单位时间内,处于可运行和不可中断状态的平均进程数,即平均活跃进程数。

可运行状态的进程:正在使用 CPU 或者正在等待 CPU 的进程,即 ps 时看到的 R 状态进程。

不可中断状态的进程:正处于内核态关键流程中的进程,且这些进程不可被打断,如等待硬件 I/O 响应,即 ps 时看到的 D 状态进程。

平均负载高于 CPU 数量的 70% 时,就应该分析排查负载高的问题了。

查看 CPU 个数:

$ grep 'model name' /proc/cpuinfo
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
model name    : Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz

2 CPU 密集型

CPU 密集型,使用大量 CPU 会导致平均负载升高。

模拟一个 CPU 使用率为 100% 的场景:

$ stress --cpu 1 --timeout 600
stress: info: [6258] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd

查看平均负载变化情况:

# -d 表示高亮显示变化的区域
$ watch -d uptime
Every 2.0s: uptime                                                                                          Sat Sep 25 16:12:04 2021

 16:12:04 up 35 days, 19:21, 14 users,  load average: 0.98, 0.52, 0.27

mpstat 可实时查看每个 CPU 的性能指标:

# -P ALL 表示监控所有 CPU,5 表示每隔 5s 输出一组数据
$ mpstat -P ALL 5
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all    6.29    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   93.69
Average:       0    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
Average:       1    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
Average:       2    0.05    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.95
Average:       3    0.02    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.98
Average:       4  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
Average:       5    0.13    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   99.85
Average:       6    0.16    0.00    0.05    0.00    0.00    0.00    0.00    0.00    0.00   99.78
Average:       7    0.00    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   99.98
Average:       8    0.20    0.00    0.02    0.00    0.00    0.02    0.00    0.00    0.00   99.76
Average:       9    0.05    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   99.93
Average:      10    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
Average:      11    0.00    0.00    0.04    0.00    0.00    0.00    0.00    0.00    0.00   99.96
Average:      12    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
Average:      13    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
Average:      14    0.00    0.00    0.09    0.00    0.00    0.00    0.00    0.00    0.00   99.91
Average:      15    0.02    0.00    0.04    0.02    0.00    0.00    0.00    0.00    0.00   99.93

可以看到,有一个 CPU 的使用率达到了 100%,但 I/O 为 0,说明负载升高是由于 CPU 利用率为 100% 导致的。

pidstat 可实时查看进程的 CPU、内存、I/O 及上下文切换等性能指标。

# -u 表示显示各个 CPU 的使用统计
# 5 表示每 5s 采样一次
# 1 表示一共采样 1 次
$ pidstat -u 5 1
Linux 4.15.0-142-generic (ubuntu)     2021年09月25日     _x86_64_    (16 CPU)

16时17分53秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
16时17分58秒   111      1106    0.20    0.20    0.00    0.40     8  avahi-daemon
16时17分58秒   123      1411    1.60    0.40    0.00    2.00     8  nxserver.bin
16时17分58秒  1000      7387  100.20    0.00    0.00  100.20     4  stress

Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:      111      1106    0.20    0.20    0.00    0.40     -  avahi-daemon
Average:      123      1411    1.60    0.40    0.00    2.00     -  nxserver.bin
Average:     1000      7387  100.20    0.00    0.00  100.20     -  stress

可以看到,是 stress 进程的 CPU 使用率为 100%

  • usr 用户态 CPU 使用率
  • system 内核态 CPU 使用率
  • guest 运行虚拟机 CPU 使用率
  • wait 等待 CPU 使用率
  • CPU 总的 CPU 使用率

3 I/O 密集型

I/O 密集型,等待 I/O 也会导致平均负载升高,但 CPU 利用率不一定升高。

模拟 I/O 压力:

$ stress -i 1 --timeout 60
stress: info: [7805] dispatching hogs: 0 cpu, 1 io, 0 vm, 0 hdd

CPU 负载升高:

$ watch -d uptime
Every 2.0s: uptime                                                                                          Sat Sep 25 16:25:30 2021

 16:25:30 up 35 days, 19:34, 14 users,  load average: 0.92, 0.71, 0.56

一个 CPU 的 iowait 升高:

$ mpstat -P ALL 5
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all    0.12    0.00    1.07    3.15    0.00    0.02    0.00    0.00    0.00   95.65
Average:       0    0.02    0.00    0.05    0.00    0.00    0.05    0.00    0.00    0.00   99.88
Average:       1    0.03    0.00    0.03    0.00    0.00    0.01    0.00    0.00    0.00   99.93
Average:       2    0.25    0.00    0.04    0.00    0.00    0.00    0.00    0.00    0.00   99.71
Average:       3    0.05    0.00    0.04    0.00    0.00    0.00    0.00    0.00    0.00   99.91
Average:       4    0.16    0.00    0.14    0.00    0.00    0.00    0.00    0.00    0.00   99.70
Average:       5    0.03    0.00    0.05    0.00    0.00    0.00    0.00    0.00    0.00   99.92
Average:       6    0.02    0.00    0.05    0.00    0.00    0.00    0.00    0.00    0.00   99.93
Average:       7    0.02    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   99.96
Average:       8    0.68    0.00    0.15    0.00    0.00    0.09    0.00    0.00    0.00   99.08
Average:       9    0.35    0.00    0.08    0.00    0.00    0.00    0.00    0.00    0.00   99.57
Average:      10    0.04    0.00    0.06    0.00    0.00    0.00    0.00    0.00    0.00   99.89
Average:      11    0.04    0.00    0.04    0.00    0.00    0.00    0.00    0.00    0.00   99.92
Average:      12    0.03    0.00    0.06    0.00    0.00    0.00    0.00    0.00    0.00   99.91
Average:      13    0.01    0.00    0.02    0.00    0.00    0.00    0.00    0.00    0.00   99.96
Average:      14    0.03    0.00    0.22    0.00    0.00    0.00    0.00    0.00    0.00   99.75
Average:      15    0.11    0.00   16.99   53.54    0.00    0.13    0.00    0.00    0.00   29.23

stress 进程导致 iowait 升高:

walle@ubuntu:~$ pidstat -u 5 1
Linux 4.15.0-142-generic (ubuntu)     2021年09月25日     _x86_64_    (16 CPU)

16时26分41秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
16时26分46秒     0       293    0.00    4.40    0.00    4.40    15  kworker/15:1H
16时26分46秒   111      1106    1.20    0.60    0.00    1.80     8  avahi-daemon
16时26分46秒   106      1119    0.20    0.00    0.00    0.20    11  dbus-daemon
16时26分46秒   123      1411    1.60    0.60    0.00    2.20     9  nxserver.bin
16时26分46秒     0      1619    0.00    0.20    0.00    0.20    14  irq/145-nvidia
16时26分46秒  1000      3229    0.60    0.00    0.00    0.60     2  compiz
16时26分46秒  1000      8001    0.20   19.40    0.00   19.60    15  stress
16时26分46秒  1000      8187    0.00    0.20    0.00    0.20     5  pidstat
16时26分46秒  1000     21631    0.20    0.00    0.00    0.20    14  docker
16时26分46秒     0     30401    0.00    0.20    0.00    0.20     7  nxclient.bin

Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:        0       293    0.00    4.40    0.00    4.40     -  kworker/15:1H
Average:      111      1106    1.20    0.60    0.00    1.80     -  avahi-daemon
Average:      106      1119    0.20    0.00    0.00    0.20     -  dbus-daemon
Average:      123      1411    1.60    0.60    0.00    2.20     -  nxserver.bin
Average:        0      1619    0.00    0.20    0.00    0.20     -  irq/145-nvidia
Average:     1000      3229    0.60    0.00    0.00    0.60     -  compiz
Average:     1000      8001    0.20   19.40    0.00   19.60     -  stress
Average:     1000      8187    0.00    0.20    0.00    0.20     -  pidstat
Average:     1000     21631    0.20    0.00    0.00    0.20     -  docker
Average:        0     30401    0.00    0.20    0.00    0.20     -  nxclient.bin

4 大进程场景

$ stress -c 20 --timeout 600
stress: info: [8276] dispatching hogs: 16 cpu, 0 io, 0 vm, 0 hdd

32 个进程在抢占 16 个 CPU:

$ pidstat -u 5 1
Linux 4.15.0-142-generic (ubuntu)     2021年09月25日     _x86_64_    (16 CPU)

16时39分50秒   UID       PID    %usr %system  %guest    %CPU   CPU  Command
16时39分55秒     0      1619    0.00    0.20    0.00    0.20    14  irq/145-nvidia
16时39分55秒  1000      8545    0.20    0.00    0.00    0.20     4  watch
16时39分55秒  1000      8607   51.10    0.00    0.00   51.10    11  stress
16时39分55秒  1000      8608   45.31    0.00    0.00   45.31     2  stress
16时39分55秒  1000      8609   49.70    0.00    0.00   49.70    14  stress
16时39分55秒  1000      8610   54.09    0.00    0.00   54.09     9  stress
16时39分55秒  1000      8611   56.29    0.00    0.00   56.29    12  stress
16时39分55秒  1000      8612   43.71    0.00    0.00   43.71     4  stress
16时39分55秒  1000      8613   62.67    0.00    0.00   62.67    11  stress
16时39分55秒  1000      8614   48.30    0.00    0.00   48.30     0  stress
16时39分55秒  1000      8615   54.69    0.00    0.00   54.69    10  stress
16时39分55秒  1000      8616   50.50    0.00    0.00   50.50    12  stress
16时39分55秒  1000      8617   52.10    0.00    0.00   52.10    15  stress
16时39分55秒  1000      8618   42.12    0.00    0.00   42.12     6  stress
16时39分55秒  1000      8619   57.88    0.00    0.00   57.88     7  stress
16时39分55秒  1000      8620   43.31    0.00    0.00   43.31     7  stress
16时39分55秒  1000      8621   46.31    0.00    0.00   46.31     1  stress
16时39分55秒  1000      8622   47.70    0.00    0.00   47.70    10  stress
16时39分55秒  1000      8623   49.90    0.00    0.00   49.90    14  stress
16时39分55秒  1000      8624   42.91    0.00    0.00   42.91     5  stress
16时39分55秒  1000      8625   49.90    0.00    0.00   49.90     6  stress
16时39分55秒  1000      8626   51.70    0.00    0.00   51.70     4  stress
16时39分55秒  1000      8627   43.91    0.00    0.00   43.91     0  stress
16时39分55秒  1000      8628   51.30    0.00    0.00   51.30     3  stress
16时39分55秒  1000      8629   42.71    0.00    0.00   42.71     8  stress
16时39分55秒  1000      8630   49.90    0.00    0.00   49.90     2  stress
16时39分55秒  1000      8631   42.51    0.00    0.00   42.51     8  stress
16时39分55秒  1000      8632   45.11    0.00    0.00   45.11    13  stress
16时39分55秒  1000      8633   63.67    0.00    0.00   63.67     3  stress
16时39分55秒  1000      8634   54.09    0.00    0.00   54.09    15  stress
16时39分55秒  1000      8635   46.91    0.00    0.00   46.91     5  stress
16时39分55秒  1000      8636   47.31    0.00    0.00   47.31    13  stress
16时39分55秒  1000      8637   56.09    0.00    0.00   56.09     9  stress
16时39分55秒  1000      8638   54.89    0.00    0.00   54.89     1  stress

参考

《Linux性能优化实战》倪鹏飞.