基础篇:到底应该怎么理解“平均负载”

root@Test:/home/test# uptime 
 08:41:38 up 3 days,  5:40,  2 users,  load average: 0.00, 0.03, 0.02

前⾯的⼏列分别是当前时间、系统运⾏时间以及正在登录⽤户数。⽽最后三个数字呢,依次则是过去1分钟、5分钟、15分钟的平均负载(Load Average)。

平均负载

平均负载是指单位时间内,系统处于可运⾏状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和CPU使⽤率并没有直接关系。

  • 可运⾏状态:是指正在使⽤CPU或者正在等待CPU的进程,也就是我们常⽤ps命令看到的,处于R状态(Running或 Runnable)的进程。
  • 不可中断状态:是指正处于内核态关键流程中的进程,并且这些流程是不可打断的,⽐如最常⻅的是等待硬件设备的I/O响应,也就是我们在ps命令中看到的D状态(Uninterruptible Sleep,也称为Disk Sleep)的进程。⽐如,当⼀个进程向磁盘读写数据时,为了保证数据的⼀致性,在得到磁盘回复前,它是不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程被打断了,就容易出现磁盘数据与进程数据不⼀致的问题。所以,不可中断状态实际上是系统对进程和硬件设备的⼀种保护机制

因此,可以简单理解为,平均负载其实就是平均活跃进程数。平均活跃进程数,直观上的理解就是单位时间内的活跃进程数,但它实际上是活跃进程数的指数衰减平均值。这个“指数衰减平均”的详细含义你不⽤计较,这只是系统的⼀种更快速的计算⽅式,你把它直接当成活跃进程数的平均值也没问题。

既然平均的是活跃进程数,那么最理想的,就是每个CPU上都刚好运⾏着⼀个进程,这样每个CPU都得到了充分利⽤。⽐如当平均负载为2时,意味着什么呢?

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

 

平均负载为多少时合理

  • 执行uptime,最后三个数字依次则是过去1分钟、5分钟、15分钟的平均负载(Load Average)
    root@Test:/home/test# uptime 
     08:41:38 up 3 days,  5:40,  2 users,  load average: 0.00, 0.03, 0.02
  • 执行top/nproc查到cpu个数,当平均负载⽐ CPU 个数还⼤的时候,系统已经出现了过载
    • 如果1分钟、5分钟、15分钟的三个值基本相同,或者相差不⼤,那就说明系统负载很平稳。
    • 如果1分钟的值远⼩于15 分钟的值,就说明系统最近1分钟的负载在减少,⽽过去15分钟内却有很⼤的负载。
    • 如果1分钟的值远⼤于 15 分钟的值,就说明最近1分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。⼀旦1分钟的平均负载接近或超过了CPU的个数,就意味着系统正在发⽣过载的问题,这时就得分析调查是哪⾥导致的问题,并要想办法优化了。
  • 当平均负载⾼于 CPU 数量70%的时候,你就应该分析排查负载⾼的问题了。⼀旦负载过⾼,就可能导致进程响应变慢,进⽽影响服务的正常功能。

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

 

平均负载与CPU使⽤率

平均负载不等于 CPU 使⽤率,平均负载是指单位时间内,处于可运⾏状态和不可中断状态的进程数。所以,它不仅包括了正在使⽤ CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。⽽ CPU 使⽤率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不⼀定完全对应。⽐如:

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

 

平均负载案例分析

用 htop,top 和 pidstat ⼯具,找出平均负载升⾼的根源。预先安装 stress 和 sysstat 包,如 apt install stress sysstat

  1. stress 是⼀个 Linux 系统压⼒测试⼯具,这⾥我们⽤作异常进程模拟平均负载升⾼的场景。
  2. sysstat 包含了常⽤的 Linux 性能⼯具,⽤来监控和分析系统的性能。我们的案例会⽤到这个包的两个命令 mpstat 和 pidstat
    1. mpstat 是⼀个常⽤的多核 CPU 性能分析⼯具,⽤来实时查看每个 CPU 的性能指标,以及所有CPU的平均指标。
    2. pidstat 是⼀个常⽤的进程性能分析⼯具,⽤来实时查看进程的 CPU、内存、I/O 以及上下⽂切换等性能指标

场景⼀:CPU 密集型进程

CPU密集型进程指的是进程数不多,但是计算量非常大,此时负载等于CPU使用率

  • 在第⼀个终端运⾏ stress 命令,模拟⼀个 CPU 使⽤率 100% 的场景:
    stress --cpu 1 --timeout 600
  • 在第⼆个终端运⾏uptime查看平均负载的变化情况
    watch -d uptime
    08:00:37 up 3 days,  1:54,  8 users,  load average: 1.00, 2.12, 2.41
  • 在第三个终端运⾏mpstat查看 CPU 使⽤率的变化情况:-P ALL 表示监控所有CPU,后⾯数字5表示间隔5秒后输出⼀组数据
    root@Test:/home/test# mpstat -P ALL 5
    Linux 5.15.0-119-generic (Test) 	09/14/2024 	_x86_64_	(4 CPU)
    
    08:01:32 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
    08:01:37 AM  all   25.08    0.00    0.10    0.00    0.00    0.05    0.00    0.00    0.00   74.77
    08:01:37 AM    0  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
    08:01:37 AM    1    0.20    0.00    0.00    0.00    0.00    0.20    0.00    0.00    0.00   99.60
    08:01:37 AM    2    0.00    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   99.80
    08:01:37 AM    3    0.00    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00   99.80

     

从终端⼆中可以看到,1 分钟的平均负载为 1.00,⽽从终端三中还可以看到,正好有⼀个 CPU 的使⽤率为100%,但它的 iowait 只有 0。这说明,平均负载的升⾼正是由于 CPU 使⽤率为 100%。那么,到底是哪个进程导致了 CPU 使⽤率为 100% 呢?使⽤ pidstat 来查询:从这⾥可以明显看到,stress进程的CPU使⽤率为100%。

  • 在第四个终端运⾏pidstat查看进程情况:间隔5秒后输出⼀组数据
    root@Test:/home/test# pidstat -u 1 5
    Linux 5.15.0-119-generic (Test)     09/14/2024     _x86_64_    (4 CPU)
    
    08:05:06 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
    08:05:07 AM  1007      3954    0.00    0.99    0.00    0.00    0.99     3  mysqld
    08:05:07 AM     0    284449  100.99    0.00    0.00    0.00  100.99     1  stress
    08:05:07 AM     0    284454    0.99    0.99    0.00    0.00    1.98     3  pidstat

 

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

  • 运⾏ stress 命令模拟 I/O 压⼒,即不停地执⾏ sync,此时系统负载增加
    stress-ng -i 1 --hdd 1 --hdd-opts sync --timeout 600
  • 第二个终端运⾏mpstat查看 CPU 使⽤率的变化情况:
    root@Test:/home/test# mpstat -P ALL 5
    Linux 5.15.0-119-generic (Test) 	09/14/2024 	_x86_64_	(4 CPU)
    
    08:19:36 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
    08:19:41 AM  all    6.27    0.00   15.03   32.09    0.00    0.41    0.00    0.00    0.00   46.20
    08:19:41 AM    0    2.62    0.00   10.89   20.77    0.00    0.40    0.00    0.00    0.00   65.32
    08:19:41 AM    1    2.88    0.00    8.64   23.87    0.00    0.41    0.00    0.00    0.00   64.20
    08:19:41 AM    2   15.48    0.00   26.88   43.99    0.00    0.61    0.00    0.00    0.00   13.03
    08:19:41 AM    3    4.08    0.00   13.67   39.80    0.00    0.20    0.00    0.00    0.00   42.24

从这⾥可以看到,CPU 的iowait 非常高。这说明,平均负载的升⾼是由于 iowait 的升⾼。接着⽤ pidstat 来查询相关进程

  • 在第三个终端运⾏pidstat查看进程情况:间隔5秒后输出⼀组数据,发现是由stress-ng进程导致CPU负载高
    root@Test:/home/test# pidstat -d -u 5 5
    Linux 5.15.0-119-generic (Test) 	09/14/2024 	_x86_64_	(4 CPU)
    
    08:32:52 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
    08:32:57 AM     0        13    0.00    0.20    0.00    0.00    0.20     0  ksoftirqd/0
    08:32:57 AM     0        14    0.00    0.20    0.00    0.00    0.20     0  rcu_sched
    08:32:57 AM     0        28    0.00    0.20    0.00    0.00    0.20     2  ksoftirqd/2
    08:32:57 AM     0       152    0.00    0.20    0.00    0.00    0.20     2  kworker/2:1H-kblockd
    08:32:57 AM     0       198    0.00    0.20    0.00    0.00    0.20     3  kworker/3:1H-kblockd
    08:32:57 AM     0       487    0.00    1.59    0.00    0.20    1.59     3  jbd2/dm-0-8
    08:32:57 AM     0       565    0.00    0.20    0.00    0.00    0.20     0  systemd-journal
    08:32:57 AM     0       810    0.40    0.20    0.00    0.00    0.60     2  falcon-sensor-b
    08:32:57 AM     0      2332    0.20    0.00    0.00    0.00    0.20     1  ssm-agent-worke
    08:32:57 AM  1007      3954    0.20    0.20    0.00    0.00    0.40     3  mysqld
    08:32:57 AM     0    270327    0.00    3.78    0.00    0.80    3.78     1  kworker/u256:2-flush-253:0
    08:32:57 AM     0    284436    0.00    3.78    0.00    0.80    3.78     2  kworker/u256:0-flush-253:0
    08:32:57 AM     0    284438    0.00    0.40    0.00    0.00    0.40     0  kworker/u256:3-flush-253:0
    08:32:57 AM     0    284725    0.00    4.58    0.00    0.60    4.58     1  kworker/u256:4+flush-253:0
    08:32:57 AM     0    285023    0.20    0.00    0.00    0.00    0.20     0  kworker/0:0-events
    08:32:57 AM     0    285052    0.60   10.56    0.00    2.39   11.16     2  stress-ng
    08:32:57 AM     0    285053   27.49   31.27    0.00    1.79   58.76     0  stress-ng
    08:32:57 AM     0    285058    0.20    0.00    0.00    0.00    0.20     3  pidstat

 

场景三:⼤量进程的场景

当系统中运⾏进程超出 CPU 运⾏能⼒时,就会出现等待 CPU 的进程。⽐如,我们使⽤ stress模拟 16 个进程,由于系统只有 4 个CPU,明显⽐ 16 个进程要少得多,因⽽,系统的 CPU 处于严重过载状态

  • 运⾏ stress 命令模拟大量进程场景,此时系统负载增加
    stress -c 8 --timeout 600
  • 第二个终端运⾏mpstat查看 CPU 使⽤率的变化情况,此时CPU负载高,但是iowait低
    08:39:13 AM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
    08:39:18 AM  all   99.95    0.00    0.05    0.00    0.00    0.00    0.00    0.00    0.00    0.00
    08:39:18 AM    0  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
    08:39:18 AM    1   99.80    0.00    0.20    0.00    0.00    0.00    0.00    0.00    0.00    0.00
    08:39:18 AM    2  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
    08:39:18 AM    3  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
  • 在第三个终端运⾏pidstat查看进程情况。可以看出,16 个进程在争抢 4 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)⾼达 70%。这些超出 CPU计算能⼒的进程,最终导致 CPU 过载。
    root@Test:/home/test# pidstat -u 1 5
    Linux 5.15.0-119-generic (Test) 	09/14/2024 	_x86_64_	(4 CPU)
    
    08:44:02 AM   UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
    08:44:03 AM     0      2332    0.93    0.00    0.00    0.00    0.93     3  ssm-agent-worke
    08:44:03 AM     0    285023    0.93    0.00    0.00    0.00    0.93     0  kworker/0:0-events
    08:44:03 AM     0    285092   23.15    0.00    0.00   73.15   23.15     0  stress
    08:44:03 AM     0    285093   24.07    0.00    0.00   71.30   24.07     3  stress
    08:44:03 AM     0    285094   24.07    0.00    0.00   72.22   24.07     0  stress
    08:44:03 AM     0    285095   23.15    0.00    0.00   72.22   23.15     0  stress
    08:44:03 AM     0    285096   24.07    0.00    0.00   72.22   24.07     1  stress
    08:44:03 AM     0    285097   24.07    0.00    0.00   70.37   24.07     1  stress
    08:44:03 AM     0    285098   24.07    0.00    0.00   72.22   24.07     3  stress
    08:44:03 AM     0    285099   24.07    0.00    0.00   70.37   24.07     1  stress
    08:44:03 AM     0    285100   23.15    0.00    0.00   71.30   23.15     1  stress
    08:44:03 AM     0    285101   24.07    0.00    0.00   71.30   24.07     2  stress
    08:44:03 AM     0    285102   24.07    0.00    0.00   71.30   24.07     3  stress
    08:44:03 AM     0    285103   24.07    0.00    0.00   72.22   24.07     2  stress
    08:44:03 AM     0    285104   24.07    0.00    0.00   71.30   24.07     2  stress
    08:44:03 AM     0    285105   23.15    0.00    0.00   69.44   23.15     0  stress
    08:44:03 AM     0    285106   24.07    0.00    0.00   72.22   24.07     2  stress
    08:44:03 AM     0    285107   23.15    0.00    0.00   71.30   23.15     3  stress
    08:44:03 AM     0    285109    0.00    0.93    0.00    0.93    0.93     0  pidstat


⼩结

平均负载提供了⼀个快速查看系统整体性能的⼿段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪⾥出现了瓶颈。所以,在理解平均负载时,也要注意:

  1. 平均负载⾼有可能是 CPU 密集型进程导致的;
  2. 平均负载⾼并不⼀定代表 CPU 使⽤率⾼,还有可能是 I/O 更繁忙了;
  3. 当发现负载⾼的时候,你可以使⽤ mpstat、pidstat 等⼯具,辅助分析负载的来源。

 

posted @ 2024-09-06 17:40  BinBin-HF  阅读(19)  评论(0编辑  收藏  举报