02-基础篇:到底应该怎么理解“平均负载”
引子
每次发现系统变慢时,我们通常做的第一件事,就是执行top或者uptime命令,来了解系统的负载情况
uptime命令
[root@local_sa_192-168-1-6 ~]# uptime
15:58:04 up 3 min, 3 users, load average: 0.20, 0.46, 0.23
输出结果解释
#15:58:04: 当前时间
#up 3 min: 系统运行时间
#3 users: 当前登录系统的用户数
#load average: 0.20, 0.46, 0.23: 过去1分钟、5分钟、15分钟的平均负载(LoadAverage)
平均负载是什么
【平均负载】是指单位时间内,系统处于【可运行状态】和【不可中断状态】的平均进程数
也就是平均活跃进程数,它和 CPU 使用率并没有直接关系
【可运行状态】的进程,是指正在使用CPU或者正在等待CPU的进程,也就是我们常用top命令看到的
处于R状态(Running或Runnable)的进程
【不可中断状态】的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的
比如最常见的是等待硬件设备的I/O响应
也就是我们在top命令中看到的D状态(Uninterruptible Sleep,也称为Disk Sleep)的进程
比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前
它是不能被其他进程或者中断打断的
这个时候的进程就处于不可中断状态
如果此时的进程被打断了,就容易出现磁盘数据与进程数据不一致的问题
所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制
因此,你可以简单理解为,【平均负载其实就是平均活跃进程数】
既然平均的是活跃进程数,那么最理想的,就是每个CPU上都刚好运行着一个进程,
这样每个CPU都得到了充分利用。比如当平均负载为2时,意味着什么呢?
1.在只有2 个CPU的系统上,意味着所有的CPU都刚好被完全占用
2.在4个CPU的系统上,意味着CPU有50%的空闲
3.而在只有1个CPU的系统中,则意味着有一半的进程竞争不到CPU
平均负载为多少时合理
我们知道,平均负载最理想的情况是等于CPU个数
所以在评判平均负载时,首先你要知道系统有几个CPU(cpu逻辑个数)
可以通过top命令或者从文件/proc/cpuinfo中读取
# /proc/cpuinfo
[root@local_sa_192-168-1-6 ~]# grep "model name" /proc/cpuinfo
model name : QEMU Virtual CPU version (cpu64-rhel6)
model name : QEMU Virtual CPU version (cpu64-rhel6)
[root@local_sa_192-168-1-6 ~]# grep "model name" /proc/cpuinfo |wc -l
2
# top --> 按数字 1
[root@local_sa_192-168-1-6 ~]# top
top - 16:21:10 up 26 min, 3 users, load average: 0.00, 0.01, 0.05
Tasks: 179 total, 1 running, 178 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
有了CPU个数,我们就可以判断出,当平均负载比CPU个数还大的时候,系统已经出现了过载
不过,且慢,我们在例子中可以看到,平均负载有三个数值,到底该参考哪一个呢?
【实际上,都要看。三个不同时间间隔的平均值,其实给我们提供了,分析系统负载趋势的数据来源,让我们能更全面、更立体地理解目前的负载状况】
1.如果1分钟、5分钟、15分钟的三个值基本相同,或者相差不大,那就说明系统负载很平稳
2.如果1分钟的值远小于15分钟的值,就说明系统最近1分钟的负载在减少,而过去15分钟内却有很大的负载
3.如果1分钟的值远大于15分钟的值,就说明最近1分钟的负载在增加
这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察
4.一旦1分钟的平均负载接近或超过了CPU的个数,就意味着系统正在发生过载的问题
这时就得分析调查是哪里导致的问题,并要想办法优化了
举个例子,假设我们在一个单CPU系统上看到平均负载为1.73,0.60,7.98
那么说明在过去1分钟内,系统有73%的超载,
而在15分钟内,有698%的超载,
从整体趋势来看,系统的负载在降低(15*73=1095)
在实际生产环境中,平均负载多高时,需要我们重点关注呢?
【当平均负载高于CPU数量70%的时候】
就应该分析排查负载高的问题了,一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能
但70%这个数字并不是绝对的
最推荐的方法,还是把系统的平均负载监控起来,
然后根据更多的历史数据,判断负载的变化趋势。
当发现负载有明显升高趋势时,比如说负载翻倍了,你再去做分析和调查
平均负载与CPU使用率区别
平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数
所以,它不仅包括了正在使用CPU的进程,还包括等待CPU和等待I/O的进程
CPU使用率,是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应
比如
1.CPU密集型进程,使用大量CPU会导致平均负载升高,此时这两者是一致的
2.I/O密集型进程,等待I/O也会导致平均负载升高,但CPU使用率不一定很高
3.大量等待CPU的进程调度也会导致平均负载升高,此时的CPU使用率也会比较高
平均负载案例分析
准备工作
以三个示例分别来看这三种情况,并用iostat、mpstat、pidstat等工具,找出平均负载升高的根源
机器配置:2CPU,4GB内存 centos7.6
预先安装 stress 和 sysstat 包
[root@local_sa_192-168-1-6 ~]# rpm -qa stress
stress-1.0.4-16.el7.x86_64
[root@local_sa_192-168-1-6 ~]# rpm -qa sysstat
sysstat-11.7.3-2.el8.x86_64
stress 是一个Linux系统压力测试工具,这里用作异常进程模拟平均负载升高的场景
sysstat 包含了常用的Linux性能工具,用来监控和分析系统的性能。
案例中会用到这个包的两个命令mpstat和pidstat
mpstat 是一个常用的多核CPU性能分析工具,用来实时查看每个CPU的性能指标,以及所有CPU的平均指标
pidstat 是一个常用的进程性能分析工具,用来实时查看进程的CPU、内存、I/O以及上下文切换等性能指标
场景一:CPU 密集型进程
1.第一个终端运行 stress 命令,模拟一个CPU 使用率 100% 的场景
[root@local_sa_192-168-1-6 ~]# stress --cpu 1 --timeout 600
stress: info: [13051] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
2.在第二个终端运行 uptime 查看平均负载的变化情况
# watch动态显示数值变化
# -d 高亮显示变化的区域
[root@local_sa_192-168-1-6 ~]# watch -d uptime
17:07:51 up 1:13, 3 users, load average: 1.00, 0.83, 0.46
3.第三个终端运行 mpstat 查看CPU使用率的变化情况
# -P ALL 表示监控所有cpu,后面的数字5表示间隔5秒输出一组数据
[root@local_sa_192-168-1-6 ~]# mpstat -P ALL 5
17时08分12秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
17时08分17秒 all 50.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 50.00
17时08分17秒 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
17时08分17秒 1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 100.00
4.查看原因
从终端二中可以看到,1分钟的平均负载会慢慢增加到1.00
从终端三中还可以看到,正好有一个CPU的使用率为100%,但它的iowait只有0
这说明,平均负载的升高正是由于CPU使用率为100%
那么,到底是哪个进程导致了CPU使用率为100%呢?
可以使用 pidstat 来查询
# pidstat 查看进程占用的系统资源
# 间隔5秒后输出一组数据
# -u 查看cpu数据
[root@local_sa_192-168-1-6 ~]# pidstat -u 5 1
Linux 3.10.0-1160.31.1.el7.x86_64 (local_sa_192-168-1-6) 2021年11月08日 _x86_64_ (2 CPU)
17时12分48秒 UID PID %usr %system %guest %wait %CPU CPU Command
17时12分53秒 0 398 0.00 0.20 0.00 0.20 0.20 0 xfsaild/dm-0
17时12分53秒 0 13867 99.80 0.00 0.00 0.00 99.80 1 stress
17时12分53秒 0 13959 0.00 0.20 0.00 0.00 0.20 0 pidstat
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 398 0.00 0.20 0.00 0.20 0.20 - xfsaild/dm-0
平均时间: 0 13867 99.80 0.00 0.00 0.00 99.80 - stress
平均时间: 0 13959 0.00 0.20 0.00 0.00 0.20 - pidstat
从这里可以明显看到,stress 进程的CPU使用率为100%
场景二:I/O密集型进程
1.第一个终端,运行 stress命令,模拟 I/O 压力,即不停地执行sync
[root@local_sa_192-168-1-6 ~]# stress -i 1 --timeout 600
stress: info: [13986] dispatching hogs: 0 cpu, 1 io, 0 vm, 0 hdd
# 建议使用这条命令测试 centos系统
# 如果上一条命令不能模拟出I/O压力,那么使用这条命令
[root@local_sa_192-168-1-6 ~]# stress-ng -i 1 --hdd 1 --timeout 600
2.第二个终端运行uptime查看平均负载的变化情况
[root@local_sa_192-168-1-6 ~]# watch -d uptime
17:18:32 up 1:24, 4 users, load average: 2.06, 0.82, 0.58
3.第三个终端运行mpstat查看CPU使用率的变化情况
[root@local_sa_192-168-1-6 ~]# mpstat -P ALL 5
[root@local_sa_192-168-1-6 ~]# mpstat -P ALL 5
Linux 3.10.0-1160.31.1.el7.x86_64 (local_sa_192-168-1-6) 2021年11月08日 _x86_64_ (2 CPU)
17时24分16秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
17时24分21秒 all 0.20 0.00 0.20 99.50 0.00 0.00 0.10 0.00 0.00 0.00
17时24分21秒 0 0.20 0.00 0.20 99.60 0.00 0.00 0.00 0.00 0.00 0.00
17时24分21秒 1 0.20 0.00 0.20 99.40 0.00 0.00 0.20 0.00 0.00 0.00
4.查看
从终端二中可以看到,1分钟的平均负载会慢慢增加到2.06
从终端三中可以看到,iowait高达99%,这说明,平均负载的升高是由于iowait的升高
那么到底是哪个进程,导致iowait这么高呢?用pidstat -d 5 1来查询
# -d 查看磁盘数据
[root@local_sa_192-168-1-6 ~]# pidstat -d 5 1
Linux 3.10.0-1160.31.1.el7.x86_64 (local_sa_192-168-1-6) 2021年11月08日 _x86_64_ (2 CPU)
17时31分54秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
17时31分59秒 0 1378 0.00 0.80 0.00 0 teamviewerd
17时31分59秒 0 14012 0.00 0.00 0.00 494 kworker/u4:2
17时31分59秒 0 14521 0.00 17333.33 0.00 496 stress-ng-hdd
17时31分59秒 0 14522 0.00 0.00 0.00 500 stress-ng-io
平均时间: UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
平均时间: 0 1378 0.00 0.80 0.00 0 teamviewerd
平均时间: 0 14012 0.00 0.00 0.00 494 kworker/u4:2
平均时间: 0 14521 0.00 17333.33 0.00 496 stress-ng-hdd
平均时间: 0 14522 0.00 0.00 0.00 500 stress-ng-io
从这里可以看出 stress-ng 进程导致的
场景三:大量进程的场景
当系统中运行进程超出CPU运行能力时,就会出现等待CPU的进程
1.第一个终端,使用 stress,模拟的是 8 个进程
[root@local_sa_192-168-1-6 ~]# stress -c 8 --timeout 600
2.第二个终端运行uptime查看平均负载的变化情况
[root@local_sa_192-168-1-6 ~]# watch -d uptime
17:38:15 up 1:44, 4 users, load average: 4.68, 1.76, 1.11
3.第三个终端运行mpstat查看CPU使用率的变化情况
[root@local_sa_192-168-1-6 ~]# mpstat -P ALL 5
Linux 3.10.0-1160.31.1.el7.x86_64 (local_sa_192-168-1-6) 2021年11月08日 _x86_64_ (2 CPU)
17时39分01秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
17时39分06秒 all 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
17时39分06秒 0 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
17时39分06秒 1 99.80 0.00 0.20 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
平均时间: all 99.87 0.00 0.13 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: 0 99.89 0.00 0.11 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: 1 99.86 0.00 0.14 0.00 0.00 0.00 0.00 0.00 0.00 0.00
4.查看
# 8个进程在争抢2个CPU,每个进程等待CPU的时间(也就是代码块中的%wait列)高达75%。
# 这些超出CPU计算能力的进程,最终导致CPU过载
[root@local_sa_192-168-1-6 ~]# pidstat -u 5 1
Linux 3.10.0-1160.31.1.el7.x86_64 (local_sa_192-168-1-6) 2021年11月08日 _x86_64_ (2 CPU)
17时40分44秒 UID PID %usr %system %guest %wait %CPU CPU Command
17时40分49秒 0 1378 0.20 0.20 0.00 0.00 0.40 1 teamviewerd
17时40分49秒 0 14570 25.20 0.00 0.00 74.40 25.20 0 stress
17时40分49秒 0 14571 24.80 0.00 0.00 75.60 24.80 1 stress
17时40分49秒 0 14572 24.60 0.00 0.00 74.80 24.60 0 stress
17时40分49秒 0 14573 24.60 0.00 0.00 75.00 24.60 1 stress
17时40分49秒 0 14574 24.40 0.00 0.00 75.20 24.40 0 stress
17时40分49秒 0 14575 24.80 0.00 0.00 75.40 24.80 1 stress
17时40分49秒 0 14576 24.80 0.00 0.00 75.40 24.80 1 stress
17时40分49秒 0 14577 25.60 0.00 0.00 75.20 25.60 0 stress
17时40分49秒 0 14613 0.20 0.20 0.00 0.60 0.40 1 watch
17时40分49秒 0 14774 0.00 0.20 0.00 0.40 0.20 0 pidstat
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 1378 0.20 0.20 0.00 0.00 0.40 - teamviewerd
平均时间: 0 14570 25.20 0.00 0.00 74.40 25.20 - stress
平均时间: 0 14571 24.80 0.00 0.00 75.60 24.80 - stress
平均时间: 0 14572 24.60 0.00 0.00 74.80 24.60 - stress
平均时间: 0 14573 24.60 0.00 0.00 75.00 24.60 - stress
平均时间: 0 14574 24.40 0.00 0.00 75.20 24.40 - stress
平均时间: 0 14575 24.80 0.00 0.00 75.40 24.80 - stress
平均时间: 0 14576 24.80 0.00 0.00 75.40 24.80 - stress
平均时间: 0 14577 25.60 0.00 0.00 75.20 25.60 - stress
平均时间: 0 14613 0.20 0.20 0.00 0.60 0.40 - watch
平均时间: 0 14774 0.00 0.20 0.00 0.40 0.20 - pidstat
小结
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。
但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。
所以,在理解平均负载时,也要注意:
1.平均负载高有可能是CPU密集型进程导致的
2.平均负载高并不一定代表CPU使用率高,还有可能是I/O更繁忙了
3.当发现负载高的时候,你可以使用mpstat、pidstat等工具,辅助分析负载的来源
转载请注明出处哟~
https://www.cnblogs.com/lichengguo