平均负载
平均负载
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。
可运行状态的进程:
可运行状态的进程,是指正在使用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个数和核数:
- 使用/proc/cpuinfo文件
cat /proc/cpuinfo | grep "processor" | wc -l
#该命令会返回系统的物理CPU个数。每一行processor代表一个逻辑处理器,如果系统开启了超线程,那么这个数字可能会大于实际的物理CPU数
cat /proc/cpuinfo | grep "cpu cores" | uniq
#该命令每个物理CPU上的核心数量
- 使用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 等工具,辅助分析负载的来源。