平均负载是指单位时间内,系统处于可运行状态和不可终端状态的平均进程数,也就是平均活跃进程数,它和cpu使用率并没有直接关系。
linux的平均负载
通过uptime
命令可以看到系统的平均负载
02:34:03 // 当前时间
up 2 days, 20:14 // 系统运行时间
1 user // 正在登录用户数
load average: 0.05, 0.11, 0.14 //系统1,5,15分钟的平均负载
平均负载是指单位时间内,系统处于可运行状态和不可终端状态的平均进程数,也就是平均活跃进程数,它和cpu使用率并没有直接关系。
可运行状态的进程,是指正在使用cpu或者正在等待cpu的进程,也就是我们常用ps命令看到的,处于R状态(Running 活Runnable)的进程。
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的I/O响应,也就是我们在ps命令中看到的D状态(Uninterruptible Sleep,也称为Disk Sleep)的进程。
不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
平均负载就是平均活跃进程数
当平均负载为2的时候,意味着什么?
- 在有1个cpu的系统上,意味着有一半的进程竞争不到cpu
- 在有2个cpu的系统上,意味着所有的cpu都刚好被完全占用
- 在有4个cpu的系统上,意味着cpu有50%的空闲。
平均负载为多少时合理
平均负载最理想的情况是等于 CPU 个数。
获取cpu的个数
grep 'model name' /proc/cpuinfo | wc -l
平均负载都会有3个值,1分钟,5分钟,15分钟;这三个值都需要观察,从中可以得出系统平均负载的趋势信息
- 如果1分钟,5分钟,15分钟的三个值都进本相同,或者相差不大,那就说明系统负载很平稳
- 如果1分钟的值小于15分钟的值,那就说明最近1分钟的负载在减少,而15分钟内的负载却有很大的负载。反之就说明1分钟内的负载在增加。
当平均负载高于 CPU 数量 70% 的时候,就需要排查负载搞的问题了。 70%的这个值不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,根据历史趋势数据,判断当前是否存在问题。
平均负载与 CPU 使用率
- 平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待I/O 的进程。
- CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
平均负载案例分析
下面,我们以三个示例分别来看这三种情况,并用下列等工具,找出平均负载升高的根源。
stress
是一个 Linux 系统压力测试工具mpstat
是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。pidstat
是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
测试系统环境:
centos 7.4
工具安装
有些系统的sysstat的版本不一致,可以从官网下载
wget http://pagesperso-orange.fr/sebastien.godard/sysstat-12.1.5-1.x86_64.rpm
yum remove sysstat
yum -y install pcp-libs
rpm -ivh sysstat-12.1.5-1.x86_64.rpm
场景一:CPU 密集型进程
模拟cpu使用
# stress --cpu $(grep processor /proc/cpuinfo | wc -l) --timeout 600
stress: info: [1121] dispatching hogs: 2 cpu, 0 io, 0 vm, 0 hdd
监控负载情况
# -d 参数表示高亮显示变化的区域
# watch -d uptime
..., load average: 2.19,1.00, 0.75
查看cpu使用情况
# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据, 1是输出1组
# mpstat -P ALL 5 1
Linux 3.10.0-693.el7.x86_64 (k8s-m1) 2019年06月15日 _x86_64_ (2 CPU)
20时32分45秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
20时32分50秒 all 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时32分50秒 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
20时32分50秒 1 100.00 0.00 0.00 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 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
平均时间: 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
从uptime中可以看到,1分钟的平均负载会慢慢增加到2.19
,而从终端三中还可以看到,正好有一个CPU的使用率为100%,但它的iowait只有0。这说明,平均负载的升高正是由于CPU使用率为100%。
查看哪个进程
# 间隔 5 秒后输出一组数据
# pidstat -u 5 1
Linux 3.10.0-693.el7.x86_64 (node74-1) 2019年06月15日 _x86_64_ (2 CPU)
20时33分17秒 UID PID %usr %system %guest %wait %CPU CPU Command
20时33分22秒 0 698 0.00 0.20 0.00 0.99 0.20 0 vmtoolsd
20时33分22秒 0 3059 99.80 0.00 0.00 0.20 99.80 1 stress
20时33分22秒 0 3060 99.60 0.00 0.00 0.60 99.60 0 stress
20时33分22秒 0 3062 0.00 0.20 0.00 0.40 0.20 0 pidstat
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 698 0.00 0.20 0.00 0.99 0.20 - vmtoolsd
平均时间: 0 3059 99.80 0.00 0.00 0.20 99.80 - stress
平均时间: 0 3060 99.60 0.00 0.00 0.60 99.60 - stress
平均时间: 0 3062 0.00 0.20 0.00 0.40 0.20 - pidstat
从这里可以明显看到,stress 进程的 CPU 使用率接近为 100%。
场景二:I/O 密集型进程
模拟io压力
# stress -i 1 -d 1 --timeout 600
stress: info: [1480] dispatching hogs: 0 cpu, 1 io, 0 vm, 1 hdd
监控负载情况
# watch -d uptime
..., load average: 1.23, 1.16, 0.68
查看cpu使用率的变化
# 显示所有 CPU 的指标,并在间隔 5 秒输出一组数据
# mpstat -P ALL 5 1
Linux 3.10.0-693.el7.x86_64 (node74-1) 2019年06月15日 _x86_64_ (2 CPU)
20时34分34秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
20时34分39秒 all 0.00 0.00 3.01 76.76 0.00 0.31 0.00 0.00 0.00 19.92
20时34分39秒 0 0.00 0.00 2.77 71.70 0.00 0.64 0.00 0.00 0.00 24.89
20时34分39秒 1 0.00 0.00 3.24 81.58 0.00 0.00 0.00 0.00 0.00 15.18
平均时间: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
平均时间: all 0.00 0.00 3.01 76.76 0.00 0.31 0.00 0.00 0.00 19.92
平均时间: 0 0.00 0.00 2.77 71.70 0.00 0.64 0.00 0.00 0.00 24.89
平均时间: 1 0.00 0.00 3.24 81.58 0.00 0.00 0.00 0.00 0.00 15.18
从这里可以看到, 1分钟的平均负载会慢慢增加到 1.23,其中一个 CPU 的系统 CPU 使用率升高到了3.24,而 iowait 高达81.58%。这说明,平均负载的升高是由于 iowait 的升高。
查看是哪个进程导致的io问题
# 间隔 5 秒后输出一组数据,-u表示CPU指标 -d表示io指标
# pidstat -u -d 5 1
Linux 3.10.0-693.el7.x86_64 (node74-1) 2019年06月15日 _x86_64_ (2 CPU)
20时41分06秒 UID PID %usr %system %guest %wait %CPU CPU Command
20时41分11秒 0 3 0.00 0.20 0.00 0.00 0.20 0 ksoftirqd/0
20时41分11秒 0 9 0.00 0.20 0.00 0.00 0.20 1 rcu_sched
20时41分11秒 0 30 0.00 0.80 0.00 0.00 0.80 1 kswapd0
20时41分11秒 0 99 0.00 0.20 0.00 0.20 0.20 1 kworker/1:2
20时41分11秒 0 293 0.00 0.20 0.00 0.00 0.20 0 xfsaild/sda3
20时41分11秒 0 2496 0.00 0.60 0.00 0.40 0.60 0 kworker/0:7
20时41分11秒 0 3068 0.00 0.80 0.00 0.00 0.80 0 kworker/u256:0
20时41分11秒 0 3091 0.00 0.20 0.00 0.00 0.20 1 stress
20时41分11秒 0 3092 0.00 4.19 0.00 0.20 4.19 1 stress
20时41分11秒 0 3100 0.00 0.20 0.00 0.00 0.20 0 pidstat
20时41分06秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
20时41分11秒 0 3068 0.00 0.00 0.00 546 kworker/u256:0
20时41分11秒 0 3091 0.00 0.00 0.00 297 stress
20时41分11秒 0 3092 0.00 63148.90 0.00 481 stress
20时41分11秒 0 3099 20.76 0.00 0.00 265 run-parts
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 3 0.00 0.20 0.00 0.00 0.20 - ksoftirqd/0
平均时间: 0 9 0.00 0.20 0.00 0.00 0.20 - rcu_sched
平均时间: 0 30 0.00 0.80 0.00 0.00 0.80 - kswapd0
平均时间: 0 99 0.00 0.20 0.00 0.20 0.20 - kworker/1:2
平均时间: 0 293 0.00 0.20 0.00 0.00 0.20 - xfsaild/sda3
平均时间: 0 2496 0.00 0.60 0.00 0.40 0.60 - kworker/0:7
平均时间: 0 3068 0.00 0.80 0.00 0.00 0.80 - kworker/u256:0
平均时间: 0 3091 0.00 0.20 0.00 0.00 0.20 - stress
平均时间: 0 3092 0.00 4.19 0.00 0.20 4.19 - stress
平均时间: 0 3100 0.00 0.20 0.00 0.00 0.20 - pidstat
平均时间: UID PID kB_rd/s kB_wr/s kB_ccwr/s iodelay Command
平均时间: 0 3068 0.00 0.00 0.00 546 kworker/u256:0
平均时间: 0 3091 0.00 0.00 0.00 297 stress
平均时间: 0 3092 0.00 63148.90 0.00 481 stress
平均时间: 0 3099 20.76 0.00 0.00 265 run-parts
可以看出stress进程正在大量的进行写入操作
场景三:大量进程的场景
模拟大量进程,我们测试机cpu是2核,这里模拟8个进程
stress -c 8 --timeout 600
监控负载情况
# watch -d uptime
..., load average: 7.85, 6.61, 5.42
由于系统只有2个CPU,明显比8个进程要少得多,因而,系统的CPU处于严重过载状态,平均负载高达7.85:
使用pidstat查看进程情况
# 间隔 5 秒后输出一组数据
# pidstat -u 5 1
Linux 3.10.0-693.el7.x86_64 (node74-1) 2019年06月15日 _x86_64_ (2 CPU)
20时29分13秒 UID PID %usr %system %guest %wait %CPU CPU Command
20时29分18秒 0 99 0.00 0.20 0.00 0.40 0.20 1 kworker/1:2
20时29分18秒 0 950 0.00 0.20 0.00 0.00 0.20 1 tuned
20时29分18秒 0 2997 24.70 0.00 0.00 74.50 24.70 1 stress
20时29分18秒 0 2998 24.70 0.00 0.00 74.50 24.70 1 stress
20时29分18秒 0 2999 24.90 0.00 0.00 74.90 24.90 0 stress
20时29分18秒 0 3000 24.90 0.00 0.00 74.10 24.90 0 stress
20时29分18秒 0 3001 25.10 0.00 0.00 75.30 25.10 0 stress
20时29分18秒 0 3002 25.10 0.00 0.00 75.30 25.10 1 stress
20时29分18秒 0 3003 24.70 0.00 0.00 74.70 24.70 1 stress
20时29分18秒 0 3004 24.70 0.00 0.00 74.50 24.70 0 stress
20时29分18秒 0 3053 0.00 0.20 0.00 1.00 0.20 1 pidstat
平均时间: UID PID %usr %system %guest %wait %CPU CPU Command
平均时间: 0 99 0.00 0.20 0.00 0.40 0.20 - kworker/1:2
平均时间: 0 950 0.00 0.20 0.00 0.00 0.20 - tuned
平均时间: 0 2997 24.70 0.00 0.00 74.50 24.70 - stress
平均时间: 0 2998 24.70 0.00 0.00 74.50 24.70 - stress
平均时间: 0 2999 24.90 0.00 0.00 74.90 24.90 - stress
平均时间: 0 3000 24.90 0.00 0.00 74.10 24.90 - stress
平均时间: 0 3001 25.10 0.00 0.00 75.30 25.10 - stress
平均时间: 0 3002 25.10 0.00 0.00 75.30 25.10 - stress
平均时间: 0 3003 24.70 0.00 0.00 74.70 24.70 - stress
平均时间: 0 3004 24.70 0.00 0.00 74.50 24.70 - stress
平均时间: 0 3053 0.00 0.20 0.00 1.00 0.20 - pidstat
可以看出,8个进程在争抢2个CPU,每个进程等待CPU的时间(也就是代码块中的%wait列)高达 75%。这些超出 CPU 计算能力的进程,最终导致CPU过载。