平均负载

平均负载

平均负载是指单位时间内,系统处于可运行状态不可中断状态的平均进程数,也就是平均活跃进程数

可运行状态的进程:

可运行状态的进程,是指正在使用CPU或者正在等待CPU的进程,也就是我们常用ps命令看到的,处于R(Running 或 Runnable)状态的进程。

不可中断状态的进程:
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,也就是我们在ps命令中看到的D(Uninterruptible Sleep,也称为 Disk Sleep)状态。

eg:

当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是
不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程
被打断了,就容易出现磁盘数据与进程数据不一致的问题

eg:

ps -aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1941  0.0  0.0  20028  5268 pts/3    Ss+  15:26   0:00 bash
root      1966  0.0  0.0  20028  5272 pts/4    Ss+  15:27   0:00 bash
root      2169  0.0  0.0  20028  5284 pts/5    Ss+  16:02   0:00 bash
root      2286  0.0  0.0  20028  5268 pts/6    Ss+  16:16   0:00 bash
root      2753  0.0  0.0  20028  5268 pts/7    Ss+  17:58   0:00 bash
root      2854  6.0  0.0  20028  5240 pts/8    Ss   18:23   0:00 bash
root      2871  0.0  0.0  57200  2244 pts/8    R+   18:23   0:00 ps -aux

chatGpt给出的概念:

平均负载(Average Load)是指系统在单位时间内的平均活跃进程数。它通常用于衡量系统的繁忙程度。平均负载的计算是基于一段时间内运行队列中的平均进程数,包括正在运行和等待运行的进程。

在Linux系统中,可以使用uptime命令来查看平均负载。执行以下命令:

uptime

uptime命令的输出通常会包含当前时间、系统运行时间以及平均负载的三个值。例如:

10:30:00 up 1 day,  2:30,  2 users,  load average: 0.12, 0.08, 0.05

其中,load average后面的三个值(0.12, 0.08, 0.05)分别代表过去1分钟、5分钟和15分钟的平均负载。

  • 如果这三个值分别是1、1、1,说明系统的负载相对较高,因为它表示平均有一个进程正在运行或等待运行。
  • 如果这三个值分别是0.1、0.2、0.3,说明系统的负载相对较低。

需要注意的是,平均负载并不是指正在运行的进程的数量,而是系统处于活跃状态的进程数。当平均负载升高时,这可能是由于系统资源紧张,导致一些进程等待运行。因此,对于服务器来说,了解平均负载是监控系统性能和资源利用的一个重要指标。


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


理想情况下的平均负载:

平均负载(Average Load)是衡量操作系统运行状况的一个重要指标,它表示单位时间内系统中处于可运行状态(包括运行或等待CPU时间片)的进程数。最理想的情况是:

平均负载与系统的处理器核心数相匹配,也就是说,如果是一个单核CPU系统,那么理想的平均负载应该是1;如果是双核,则为2;以此类推。 
例如,在一个拥有4个物理核心的系统中,如果所有核心都能充分利用且没有等待IO或其他资源的进程,那么理想的平均负载就是4。```
  • 所有进程能够快速获得并完成CPU计算,无长时间阻塞在等待IO、锁或其他外部资源的状态。

  • 系统中没有因内存不足、磁盘空间不足或其他系统资源瓶颈导致的性能下降。

  • 系统中的进程数量稳定,没有突发性的大量进程创建和销毁。

    然而,在实际情况中,完全理想的负载几乎是不存在的,因为总会有一些进程在等待IO操作或其他资源,所以运维人员通常会将“理想”的平均负载设定为略低于实际CPU核心数的值,以预留一定的缓冲空间处理突发任务和IO等待等情况。

统计CPU个数和核数:

  1. 使用/proc/cpuinfo文件
cat /proc/cpuinfo | grep "processor" | wc -l
#该命令会返回系统的物理CPU个数。每一行processor代表一个逻辑处理器,如果系统开启了超线程,那么这个数字可能会大于实际的物理CPU数
cat /proc/cpuinfo | grep "cpu cores" | uniq
#该命令每个物理CPU上的核心数量
  1. 使用lscpu命令:
lscpu
Architecture:          x86_64               #CPU架构
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                16                   #CPU个数
On-line CPU(s) list:   0-15
Thread(s) per core:    2
Core(s) per socket:    8                                 #CPU核数
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 79
Model name:            Intel(R) Xeon(R) CPU E5-2682 v4 @ 2.50GHz
Stepping:              1
CPU MHz:               2494.224
BogoMIPS:              4988.44
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              256K
L3 cache:              40960K
NUMA node0 CPU(s):     0-15
Flags:                 fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl eagerfpu pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single ibrs ibpb stibp fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt spec_ctrl intel_stibp
#执行这个命令会输出详细的CPU信息,包括CPU架构、核心数、线程数(逻辑CPU数)、物理CPU数等。

3.使用nproc命令:

nproc --all
#该命令会直接返回系统的总逻辑CPU数

4.使用top命令:

top
Tasks:  15 total,   1 running,  14 sleeping,   0 stopped,   0 zombie
%Cpu(s): 19.0 us,  4.4 sy,  0.0 ni, 76.3 id,  0.3 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem : 65806528 total,   377508 free, 19388832 used, 46040188 buff/cache
KiB Swap:        0 total,        0 free,        0 used. 45870784 avail Mem
PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
1 root      20   0   11.0g   1.6g  37508 S 100.0  2.6 508:42.98 java
750 root      20   0   20028   5164   1564 S   0.0  0.0   0:00.66 bash
1715 root      20   0   20028   5272   1664 S   0.0  0.0   0:00.76 bash
1880 root      20   0   20028   5264   1656 S   0.0  0.0   0:00.71 bash
1897 root      20   0    9824   1012    520 S   0.0  0.0   0:00.57 tail
1898 root      20   0   15160   1880    932 S   0.0  0.0   0:00.12 grep
1941 root      20   0   20028   5268   1656 S   0.0  0.0   0:00.70 bash
1966 root      20   0   20028   5272   1660 S   0.0  0.0   0:00.79 bash
2169 root      20   0   20028   5284   1672 S   0.0  0.0   0:00.70 bash
2286 root      20   0   20028   5268   1656 S   0.0  0.0   0:00.71 bash
2753 root      20   0   20028   5268   1660 S   0.0  0.0   0:00.73 bash
2854 root      20   0   20028   5244   1628 S   0.0  0.0   0:00.74 bash
2959 root      20   0   20028   5168   1564 S   0.0  0.0   0:00.70 bash
2976 root      20   0    9824   1012    520 S   0.0  0.0   0:00.03 tail
3018 root      20   0   61640   2472   1500 R   0.0  0.0   0:00.11 top

平均负载与 CPU 使用率:

平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待I/O 的进程

平均负载不仅包括了正在使用CPU的进程,还包括等待CPU和等待IO的进程。CPU使用率是单位时间内CPU繁忙情况的统计。

  • 计算密集型(CPU密集型):
    使用大量 CPU 会导致平均负载升高,此时平均负载与 CPU 使用率两者是一致的
  • I/O密集型:
    等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高

大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高

常用工具

  • iostat
  • mpstat
  • pidstat

机器配置:2 CPU,8GB 内存

场景一:CPU 密集型进程

#运行 stress 命令,模拟一个 CPU 使用率 100%
stress --cpu 1 --timeout 600
# -d 参数表示高亮显示变化的区域
watch -d uptime
Every 2.0s: uptime
Tue Jan 30 19:28:37 2024 19:28:37 up 60 days, 21:35,  4 users,  load average: 1.49, 1.52, 1.27
# -P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据mpstat -P ALL 5
Average:     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest  %gnice   %idle
Average:     all   15.49    0.00    3.53    0.02    0.00    0.21    0.00    0.00    0.00   80.76
Average:       0    3.02    0.00    2.80    0.02    0.00    0.73    0.00    0.00    0.00   93.43
Average:       1    2.95    0.00    3.38    0.02    0.00    0.28    0.00    0.00    0.00   93.36
Average:       2    3.30    0.00    5.20    0.00    0.00    0.16    0.00    0.00    0.00   91.34
Average:       3    3.58    0.00    4.73    0.02    0.00    0.12    0.00    0.00    0.00   91.55
Average:       4  100.00  0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00
Average:       5    3.30    0.00    2.81    0.02    0.00    0.12    0.00    0.00    0.00   93.75
Average:       6    3.64    0.00    5.68    0.00    0.00    0.12    0.00    0.00    0.00   90.56
Average:       7    3.19    0.00    3.66    0.04    0.00    0.12    0.00    0.00    0.00   92.98

从终端二中可以看到,1 分钟的平均负载会慢慢增加到 1.00,而从终端三中还可以看到,
正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正
是由于 CPU 使用率为 100%

# 间隔 5 秒后输出一组数据
 pidstat -u 5 1
Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:        0     87893    0.00    0.20    0.00    0.20     -  kworker/5:0-events
Average:        0     89989  100.00    0.00    0.00  100.00     -  stress

从这里可以明显看到,stress 进程的 CPU 使用率为 100%

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

stress -i 1 --timeout 600
Every 2.0s: uptime
Tue Jan 30 19:38:57 2024 19:38:57 up 60 days, 21:46,  4 users,  load average: 1.89, 1.71, 1.47
# 显示所有 CPU 的指标,并在间隔 5 秒输出一组数据
mpstat -P ALL 5 1
13:41:28 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnic
13:41:33 all 0.21 0.00 12.07 32.67 0.00 0.21 0.00 0.00 0.0
13:41:33 0 0.43 0.00 23.87 67.53 0.00 0.43 0.00 0.00 0.0
13:41:33 1 0.00 0.00 0.81 0.20 0.00 0.00 0.00 0.00 0.0

从这里可以看到,1 分钟的平均负载会慢慢增加到 1.06,其中一个 CPU 的系统 CPU 使用率升高到了 23.87,而 iowait 高达 67.53%。这说明,平均负载的升高是由于 iowait 的升高。

# 间隔 5 秒后输出一组数据,-u 表示 CPU 指标
pidstat -u 5 1
Average:      UID       PID    %usr %system  %guest    %CPU   CPU  Command
Average:        0         1    0.40    1.39    0.00    1.79     -  systemd
Average:        0        10    0.00    0.20    0.00    0.20     -  rcu_sched
Average:       81      1392    0.20    0.00    0.00    0.20     -  dbus-daemon
Average:        0      1440    0.00    0.20    0.00    0.20     -  rngd
Average:        0      1444    0.20    0.20    0.00    0.40     -  systemd-logind
Average:        0    128115    0.20   92.03    0.00   92.23     -  stress

场景三:大量进程的场景

stress -c 8 --timeout 600
watch -d uptime
Every 2.0s: uptime
Tue Jan 30 19:46:03 2024 19:46:03 up 60 days, 21:53,  4 users,  load average: 11.61, 4.72, 2.60
# 间隔5秒后输出一组数据
$ pidstat -u 5 1
14:23:25      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command
14:23:30        0      3190   25.00    0.00    0.00   74.80   25.00     0  stress
14:23:30        0      3191   25.00    0.00    0.00   75.20   25.00     0  stress
14:23:30        0      3192   25.00    0.00    0.00   74.80   25.00     1  stress
14:23:30        0      3193   25.00    0.00    0.00   75.00   25.00     1  stress
14:23:30        0      3194   24.80    0.00    0.00   74.60   24.80     0  stress
14:23:30        0      3195   24.80    0.00    0.00   75.00   24.80     0  stress
14:23:30        0      3196   24.80    0.00    0.00   74.60   24.80     1  stress
14:23:30        0      3197   24.80    0.00    0.00   74.80   24.80     1  stress
14:23:30        0      3200    0.00    0.20    0.00    0.20    0.20     0  pidstat

可以看出,8 个进程在争抢 2 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。

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

  • 平均负载高有可能是 CPU 密集型进程导致的;
  • 平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了; 当发现负载高的时候,你可以使用
  • mpstat、pidstat 等工具,辅助分析负载的来源。
posted @ 2024-02-01 14:36  Emars  阅读(37)  评论(0编辑  收藏  举报