02 | 平均负载

64 阅读4分钟

1. 概述

命令如下:

$ uptime
02:34:03 up 2 days, 20:14,  1 user,  load average: 0.63, 0.83, 0.88

部分输出内容解释:

02:34:03              //当前时间
up 2 days, 20:14      //系统运行时间
1 user                //正在登录用户数

平均负载简介与关键概念

  1. 定义
    平均负载表示单位时间内,处于 可运行状态不可中断状态平均活跃进程数,与 CPU 使用率 无直接关系。
  2. 关键状态解释
    • 可运行状态 (R)
      • 进程正在使用 CPU 或等待 CPU。
      • ps 命令中标记为 R(Running 或 Runnable)。
    • 不可中断状态 (D)
      • 进程处于内核态关键流程中,无法被打断,常见于等待硬件 I/O 响应。
      • ps 命令中标记为 D(Uninterruptible Sleep)。
      • 作用:保护进程和硬件设备,避免数据不一致。
  1. 计算方法
    平均负载是活跃进程数的 指数衰减平均值,可近似理解为活跃进程数的平均值。

那么当前负载为2,代表什么?

  • 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
  • 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
  • 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。

如何判断平均负载是否健康?

理想情况下,平均负载小于等于逻辑CPU核心数是健康的,如下命令检查逻辑核心数

$ grep 'model name' /proc/cpuinfo | wc -l
2

在得知逻辑核心数的情况下,我们发现load average: 0.63, 0.83, 0.88这里有三个值,代表的是最近1、5、15分钟的负载值。所以需要看着三个值的变化曲度

  • 如果 1 分钟、5 分钟、15 分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳。
  • 但如果 1 分钟的值远小于 15 分钟的值,就说明系统最近 1 分钟的负载在减少,而过去 15 分钟内却有很大的负载。
  • 反过来,如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了。

这里我再举个例子,假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98,那么说明在过去 1 分钟内,系统有 73% 的超载,而在 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。

对于负载,我们可以从超载量和整体趋势两个维度分析,以下给出公式:


整体趋势衡量平均负载在三个时间段(1 分钟、5 分钟、15 分钟)内的变化情况。可以通过以下公式


  • 趋势增加:当趋势变化率为正值时,说明最近负载在增加。
  • 趋势平稳:当趋势变化率接近 0% 时,说明负载平稳。
  • 趋势下降:当趋势变化率为负值时,说明最近负载在下降。

平均负载和CPU使用率有什么区别?平均负载高,是否代表CPU使用率也一样高呢?首先从概念上来讲,平均负载包含了正在使用的CPU以及等待CPU和等待I/O的进程,也就是所说的可运行状态和不可中断状态的进程数。

而CPU使用率,是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应。比如:

  • CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
  • I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
  • 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。

总结来说,CPU使用率不包含不可中断进程,一般指的是I/O等待。

2. 案例

环境准备:

  • 操作系统:Ubuntu 18.04
  • 机器配置:2 CPU,8GB 内存。
  • 预先安装 stress 和 sysstat 包,如 apt install stress sysstat。

工具介绍

工具名称功能概述主要用途常用命令示例备注
stressLinux 系统压力测试工具,可模拟高负载场景。用于异常进程模拟、性能瓶颈测试等。stress --cpu 8 --timeout 30模拟 8 核 CPU 高负载 30 秒。
sysstat包含常用的 Linux 性能监控和分析工具的集合。系统性能监控、问题排查、资源使用分析等。mpstat 1 5每秒采样一次,共采样 5 次 CPU 性能。
mpstat多核 CPU 性能分析工具,监控每核及平均 CPU 指标。查看 CPU 使用率、空闲时间等性能数据。mpstat -P ALL 1 3查看所有 CPU 核心,每秒采样一次,共采样 3 次。
pidstat进程性能分析工具,监控单个进程的 CPU、内存、I/O 和上下文切换等指标。分析特定进程性能,定位资源消耗问题。pidstat -p 1234 1 5查看进程 PID 为 1234 的性能数据,每秒采样一次,共采样 5 次。

安装stress和sysstat

apt -y install stress sysstat 

2.1. 场景一:CPU 密集型进程

终端 1:

$ stress --cpu 1 --timeout 600

终端 2:

# -d 参数表示高亮显示变化的区域
$ watch -d uptime
...,  load average: 1.00, 0.75, 0.39

终端 3:

# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
$ mpstat -P ALL 5
Linux 4.15.0 (ubuntu) 09/22/18 _x86_64_ (2 CPU)
13:30:06     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
13:30:11     all   50.05    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   49.95
13:30:11       0    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
13:30:11       1  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00

pidstat查看导致CPU 100%的进程

# 间隔5秒后输出一组数据
$ pidstat -u 5 1
13:37:07      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
13:37:12        0      2962  100.00    0.00    0.00    0.00  100.00     1  stress

注意:16.04没有iowait字段。

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

终端 1:

$ stress -i 1 --timeout 600 -- 这个命令可能无法模拟IOWAIT,需要用到下面的命令

$ stress -i 1 --hdd 1 --timeout 600

终端 2:

$ watch -d uptime
...,  load average: 1.06, 0.58, 0.37

终端 3:

# 显示所有CPU的指标,并在间隔5秒输出一组数据
$ mpstat -P ALL 5 1
Linux 4.15.0 (ubuntu)     09/22/18     _x86_64_    (2 CPU)
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   23.87   67.53    0.00    0.43    0.00    0.00    0.00    7.74
13:41:33       1    0.00    0.00    0.81    0.20    0.00    0.00    0.00    0.00    0.00   98.99

# 继续使用pidstat查看哪个进程占了大量的IO
pidstat -u 5 1

2.3. 场景三:大量进程的场景

$ stress -c 8 --timeout 600

还是有点区别,CPU使用率已经100%了。因持续观察会发现,负载最终会稳定在小于8的值。此时可以查看pidstat,会发现会有大量的wait%。