「Linux」- 平均负载(Load Average)

更新日期:2020年03月06日

相关文章及学习资料

Linux Load Averages: Solving the Mystery

概念讲解:系统负载 与 平均负载

当使用 top 或 uptime 命令时,都会输出 load average 字段:

# uptime
 23:47:36 up 5 days,  2:13,  5 users,  load average: 0.99, 0.66, 0.55

# top
top - 23:47:53 up 5 days,  2:13,  5 users,  load average: 1.01, 0.67, 0.55
...

分别代表系统在前一分钟,五分钟,十五分钟的平均负载。

什么是系统负载?

系统负载展示系统的处理器、磁盘、其他资源的繁忙程度。系统负载是操作系统执行计算工作的度量,以数字形式显示。如果计算机完全空闲,则系统负载为 0。每个等待处理器资源或正在使用处理器资源的进程都会向系统负载加 1 。如果系统负载为 5,则表示由五个进程在使用处理器或者等待处理器资源。(注意,UNIX 系统通常只计算等待处理器的进程,而 Linux 还会计算其他的资源(比如等待磁盘的读写)

系统负载通常没有太大的含义:因为它在这一秒为零,那么下一秒可能为五,因为那时可能有五个进程在等待资源。这也是为什么:在 UNIX 中,显示的是某段时间内的平均负载,而不是系统负载。

什么是平均负载?

平均负载则是系统负载在一段时间内的平均值。平均负载一般是三个值 load average: 0.99, 0.66, 0.55 形式。

在几乎所有类 Unix 系统中,平均负载只计算运行或等待状态的进程,所以被称之为“CPU Load Average”。

在 Linux 中,技术上认为平均负载是内核执行队列中标记为 正在运行的进程(p->state = TASK_RUNNING)不可中断的进程(p->state = TASK_UNINTERRUPTABLE) 的平均值,所以被称之为“System Load Average”。可以简单理解为“平均负载其实就是平均活跃进程数”,它实际上是活跃进程数的指数衰减平均值(使用 EMA 算法)。

输出解读:平均负载具体含义

使用 uptime 命令来查看平均负载,也可以通过 watch -n 1 cat /proc/loadavg 文件系统查看。

如果处理器是单核的

我们以 load average: 1.05, 0.70, 5.09 为例。假如你的处理器是单核的,则表示:

	在过去的一分钟:机器平均超载 0.05 个,就是说平均有 0.05 个进程在等待处理器资源;
	在过去的五分钟:机器平均负载 0.70 个,有 0.03 的时间处理器处于空闲;
	在过去的一刻钟:机器平均超载 4.09 个,平均有 4.09 个进程在等待处理器资源;

注意,如果没有在使用,则为 0%;如果资源满载,则为 100%;那么超出的部分,就是在等待资源的进程。

如果处理器是多核的

如果平均负载为 2,则表示:

	在单核处理器上,那肯定是超载的:一个进程为使用处理器资源,而另外一个进程在等待处理器资源;
	在双核处理器上,那正好是满载的:两个进程都在使用处理器资源,并且两个进程都在使用不同的处理器资源;
	在四核处理器上,那存在着空闲的:两个进程都在使用处理器资源,并且两个进程都在使用不同的处理器资源,并且还有两个处理器的空闲的。

所以,如果要正确解读平均负载的含义,需要知道处理器的核心数,这可以使用lscpu / nproc命令。对于平均负载为 6.05 的计算机,在六核主机上是超载的,而在八核主机上则是正常的。

对于三个数据的解读

平均负载最理想的情况是等于处理器个数,首先你要知道系统有几个处理器,然后我们就可以判断出当前负载是否过高。

对于三个负载数据:
如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳;
如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载;
如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加。但有可能只是临时性的,所以就需要持续观察;

平均负载为多少时合理?

在通常情况下,当平均负载高于 CPU 数量 70% 的时候,则应该开始处理。

还有种方法是监控系统负载,更具历史数据制定合理的阈值。当长期超过该阈值之后,则应该进行处理。

模拟负载并进行测试

场景一:CPU 密集型进程

# stress --cpu 1 --timeout 600

# watch -d uptime

# mpstat -P ALL 5 // 多核 CPU 性能分析工具:-P ALL 表示监控所有 CPU;数字 5 表示间隔 5 秒后输出一组数据
04:49:48 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
04:49:53 PM  all   25.24    0.00    0.20    0.00    0.00    0.25    0.00    0.00    0.00   74.31
04:49:53 PM    0    0.20    0.00    0.20    0.00    0.00    0.99    0.00    0.00    0.00   98.61
04:49:53 PM    1    0.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   99.00
04:49:53 PM    2    0.00    0.00    0.40    0.00    0.00    0.00    0.00    0.00    0.00   99.60
04:49:53 PM    3  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00

// 此时,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0 。这说明,平均负载的升高正是由于 CPU 使用率为 100%

// 接下来,定位导致 CPU 使用率为 100% 的进程

# pidstat -u 5 1 // 进程性能分析工具:间隔 5 秒后输出一组数据
Linux 5.4.0-26-generic (workstation)    07/27/2020      _x86_64_        (4 CPU)

04:53:18 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
04:53:23 PM     0        11    0.00    0.20    0.00    0.20    0.20     2  rcu_sched
04:53:23 PM   119      1023    0.20    0.20    0.00    0.00    0.40     1  sddm-greeter
04:53:23 PM  1000    128838    0.20    0.00    0.00    0.00    0.20     2  Xorg
04:53:23 PM     0    306857    0.20    0.00    0.00    0.00    0.20     2  tmux: server
04:53:23 PM     0    685709    0.40    0.00    0.00    0.00    0.40     3  java
04:53:23 PM     0   1149436    0.00    0.20    0.00    0.00    0.20     1  kworker/1:1-mm_percpu_wq
04:53:23 PM     0   1168507  100.00    0.00    0.00    0.00  100.00     3  stress
04:53:23 PM     0   1169773    0.40    0.60    0.00    0.00    0.99     1  pidstat

// 此时会发现 CPU 使用高的进程为 stree 进程

场景二:I/O 密集型进程

# stress -i 1 --timeout 600

# watch -d uptime

# mpstat -P ALL 5 1
05:00:46 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
05:00:51 PM  all    1.18    0.00   13.39    7.61    0.00    3.68    0.00    0.00    0.00   74.14
05:00:51 PM    0    1.22    0.00   23.98   12.60    0.00    5.08    0.00    0.00    0.00   57.11
05:00:51 PM    1    0.61    0.00   28.74   17.61    0.00    8.30    0.00    0.00    0.00   44.74
05:00:51 PM    2    0.40    0.00    0.40    0.00    0.00    0.80    0.00    0.00    0.00   98.40
05:00:51 PM    3    2.55    0.00    0.00    0.00    0.00    0.43    0.00    0.00    0.00   97.02

// 此时,CPU %usr 使用并不高,但是 %sys %iowait 上升,这说明,平均负载的升高是由于 iowait 的升高

// 接下来,定位 iowait 较高的进程

# pidstat -u 5 1
Linux 5.4.0-26-generic (workstation)    07/27/2020      _x86_64_        (4 CPU)

05:03:27 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
05:03:32 PM     0        11    0.00    0.20    0.00    0.00    0.20     2  rcu_sched
05:03:32 PM     0       260    0.00    0.20    0.00    0.00    0.20     2  kworker/2:1H-kblockd
05:03:32 PM     0       267    0.00    2.98    0.00    0.00    2.98     3  kworker/3:1H-kblockd
05:03:32 PM     0       268    0.00    1.39    0.00    0.00    1.39     0  kworker/0:1H-kblockd
05:03:32 PM     0       352    0.00    7.14    0.00    0.20    7.14     1  kworker/1:1H-kblockd
05:03:32 PM     0       484    0.00    1.19    0.00    0.20    1.19     2  haveged
05:03:32 PM   119      1023    0.40    0.20    0.00    0.00    0.60     2  sddm-greeter
05:03:32 PM  1000    128838    0.00    0.20    0.00    0.00    0.20     0  Xorg
05:03:32 PM  1000    128945    0.20    0.00    0.00    0.00    0.20     0  lxqt-policykit-
05:03:32 PM     0    306857    0.20    0.00    0.00    0.00    0.20     3  tmux: server
05:03:32 PM     0    399265    0.00    0.20    0.00    0.00    0.20     2  kworker/2:0-events
05:03:32 PM     0    685709    0.40    0.00    0.00    0.00    0.40     3  java
05:03:32 PM     0   1149436    0.00    0.20    0.00    0.00    0.20     1  kworker/1:1-events
05:03:32 PM     0   1170240    1.79   43.85    0.00   11.71   45.63     1  stress
05:03:32 PM     0   1170893    0.40    0.40    0.00    0.00    0.79     3  pidstat

// 此时会发现,stree 进程的 %wait 比较高,并且 %system 也比较高

// 进一步确定 I/O 情况

# pidstat -d 5 1
Linux 5.4.0-26-generic (workstation)    07/27/2020      _x86_64_        (4 CPU)

06:14:40 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
06:14:45 PM     0   1178838      0.00      0.00      0.00     185  stress

Average:      UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
Average:        0   1178838      0.00      0.00      0.00     185  stress

注意事项:
1)这里使用 sync() 模拟负载,可能不会产生大量 I/O 压力,因此可能效果不好,导致 %iowait 不明显,可以使用 stress-ng 模拟。

场景三:大量进程的场景

在该场景下,大量进程需要使用 CPU 资源,导致负载升高:

# stress -c 8 --timeout 600

# watch -d uptime

# mpstat -P ALL 5 1
05:51:55 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
05:52:00 PM  all   99.90    0.00    0.10    0.00    0.00    0.00    0.00    0.00    0.00    0.00
05:52:00 PM    0  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
05:52:00 PM    1   99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00
05:52:00 PM    2   99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00
05:52:00 PM    3  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00

# pidstat -u 5 1
Linux 5.4.0-26-generic (workstation)    07/27/2020      _x86_64_        (4 CPU)

05:54:10 PM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
05:54:15 PM   119      1023    0.20    0.00    0.00    0.00    0.20     1  sddm-greeter
05:54:15 PM  1000    128945    0.20    0.00    0.00    0.00    0.20     0  lxqt-policykit-
05:54:15 PM     0    685709    0.40    0.00    0.00    0.00    0.40     3  java
05:54:15 PM     0   1176310   49.90    0.00    0.00   50.30   49.90     3  stress
05:54:15 PM     0   1176311   49.90    0.00    0.00   50.50   49.90     1  stress
05:54:15 PM     0   1176312   49.70    0.00    0.00   50.30   49.70     0  stress
05:54:15 PM     0   1176313   50.10    0.00    0.00   50.30   50.10     2  stress
05:54:15 PM     0   1176314   50.10    0.00    0.00   50.30   50.10     2  stress
05:54:15 PM     0   1176315   49.90    0.00    0.00   50.10   49.90     1  stress
05:54:15 PM     0   1176316   49.70    0.00    0.00   51.09   49.70     1  stress
05:54:15 PM     0   1176317   49.70    0.00    0.00   50.50   49.70     3  stress
05:54:15 PM     0   1176570    0.20    0.40    0.00    0.20    0.60     0  pidstat

注意事项

平均负载升高,并不代表 CPU 使用率的增加。因为平均负载包括不可中断进程,而不可中断进程并不一定是在使用 CPU 资源,另外平均负载还包括等待 CPU 的资源。

很多处理器具有超线程技术,我们在统计处理器个数时,应该统计逻辑核数

相关链接

如果想要了解平均负载的更多细节,可以查看下面的文章:

Understanding Linux 处理器 Load - when should you be worried?

参考文献

Understanding the Load Average on Linux and Other Unix-like Systems
Understand Linux Load Averages and Monitor Performance of Linux


ToC

相关文章及学习资料

概念讲解:系统负载 与 平均负载

什么是系统负载?

什么是平均负载?

输出解读:平均负载具体含义

如果处理器是单核的

如果处理器是多核的

对于三个数据的解读

平均负载为多少时合理?

模拟负载并进行测试

场景一:CPU 密集型进程

场景二:I/O 密集型进程

场景三:大量进程的场景

注意事项

相关链接

参考文献