Lework Study hard, improve every day.

[Linux性能优化]1.理解linux的"平均负载"

2019-06-15
lework
本文 6575 字,阅读全文约需 19 分钟

平均负载是指单位时间内,系统处于可运行状态不可终端状态的平均进程数,也就是平均活跃进程数,它和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过载。

原文地址 https://lework.github.io/2019/06/15/liunx-load/

Similar Posts

Comments