运行uptime查看平均负载
[root@master ~]# uptime 23:24:59 up 12 days, 22:57, 2 users, load average: 0.02, 0.02, 0.05
每列的意思
23:24:59 // 当前时间 up 12 days, 22:57, // 系统运行时间 2 users, // 当前登录的用户数量 load average: 0.02, 0.02, 0.05 // 分别是过去 1分钟 、10分钟 、15 分钟的负载
平均负载 :表示单位时间内系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数它和CPU使用率没有直接关系。
可运行状态的进行:表示正在使用CPU或者正在等待CPU的进程,也就是我们常用ps命令看到的处于R状态(Running或Runnable)的进程。
不可中断状态的进程:表示正处于内核关键流程中的进程,并且这些流程不可中断的;如常见的硬件设备IO响应,也就是我们在ps命令里看到D状态的进程;当向磁盘读写数据时,为保证数据一致性,在没有得到磁盘的响应时,它是不能被其他进程或者中断打断的,这时候的进程就处于不可中断状态。如果此时进程被打断,就容易出现磁盘数据与进程数据不一致现象。所以不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
可以简单理解为,平均负载就是平均活跃进程数。平均活跃进程数,直观上理解就是单位时间内的活跃进程数,它实际上是平均活跃进程数的指数衰减平均值,把它理解活跃进程数的平均值
既然是平均活跃进程数,那么最理想的就是每个CPU都刚好运行一个进程,这样每个CPU都得到充分利用,如负载为2表示什么?在只有2个CPU的系统上,意味着所有CPU刚好被占满;在只有4个CPU的系统上,意味着cpu有50% 的空闲;只有1个CPU的系统上,以为这有一半进程竞争不到CPU
平均负载最理想的情况是等于CPU个数。所有评判平均负载时首先要知道有几个CPU。查看系统CUP个数
[root@master ~]# grep 'model name' /proc/cpuinfo | wc -l 2
有CPU个数我们就可以判断,平均负载比CPU个数大的时候,系统已经出现过载;不过有新的问题来了,上面的例子平均负载3个值我们该参考那个。实际都要看,三个不同时间的间隔值。其实给我们提供了分析系统负载趋势的数据来源。让我们更全面。更立体地理解目前负载情况。如果1分钟、5分钟、15分钟的三个值基本相同,或者相差不大,说明系统负载很平稳;但如果1分钟的值远小于15分钟的值说明系统最近一分钟的负载在减小,而过去15分钟内却有很大负载;如果 1 分钟的值远大于 15 分钟的值,就说明最近 1 分钟的负载在增加,这种增加有可能只是临时性的,也有可能还会持续增加下去,所以就需要持续观察。一旦 1 分钟的平均负载接近或超过了 CPU 的个数,就意味着系统正在发生过载的问题,这时就得分析调查是哪里导致的问题,并要想办法优化了
在实际生产环境中,平均负载多高时,需要我们重点关注呢?
当平均负载高于 CPU 数量 70% 的时候,你就应该分析排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。但 70% 这个数字并不是绝对的,最推荐的方法,还是把系统的平均负载监控起来,然后根据更多的历史数据,判断负载的变化趋势。当发现负载有明显升高趋势时,比如说负载翻倍了,你再去做分析和调查
平均负载与 CPU 使用率
还是要回到平均负载的含义上来,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程
而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。
CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
以三个示例分别来看这三种情况,并用 iostat、mpstat、pidstat 等工具,找出平均负载升高的根源。
机器配置:2 CPU,8GB 内存。
预先安装 stress 和 sysstat 包,如 yum install stress sysstat。
stress 是一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场景。
而 sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能。我们的案例会用到这个包的两个命令 mpstat 和 pidstat。
mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
sysstat 建议编译安装最新版本
git clone git://github.com/sysstat/sysstat cd sysstat ./configure make install
查看系统平均负载
[root@master ~]# uptime 00:55:18 up 7 min, 1 user, load average: 0.00, 0.05, 0.05
模拟CPU 密集型进程;首先,我们在第一个终端运行 stress 命令,模拟一个 CPU 使用率 100% 的场景:
[root@master ~]# stress --cpu 1 --timeout 600 stress: info: [5896] dispatching hogs: 1 cpu, 0 io, 0 vm, 0 hdd
接着,在第二个终端运行 uptime 查看平均负载的变化情况:
Every 2.0s: uptime Thu Mar 12 01:00:13 2020 01:00:13 up 12 min, 3 users, load average: 1.03, 0.58, 0.26
最后,在第三个终端运行 mpstat 查看 CPU 使用率的变化情况:-P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
[root@master ~]# mpstat -P ALL 5 Linux 3.10.0-957.el7.x86_64 (master) 2020年03月12日 _x86_64_ (2 CPU) 01时01分27秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01时01分32秒 all 50.10 0.00 0.10 0.00 0.00 0.00 0.00 0.00 0.00 49.80 01时01分32秒 0 0.00 0.00 0.40 0.00 0.00 0.00 0.00 0.00 0.00 99.60 01时01分32秒 1 99.80 0.00 0.00 0.00 0.00 0.20 0.00 0.00 0.00 0.00
从终端二中可以看到,1 分钟的平均负载会慢慢增加到 1.00,而从终端三中还可以看到,正好有一个 CPU 的使用率为 100%,但它的 iowait 只有 0。这说明,平均负载的升高正是由于 CPU 使用率为 100% 。
那么,到底是哪个进程导致了 CPU 使用率为 100% 呢?你可以使用 pidstat 来查询:
[root@master ~]# pidstat -u 5 1 Linux 3.10.0-957.el7.x86_64 (master) 2020年03月12日 _x86_64_ (2 CPU) 01时04分52秒 UID PID %usr %system %guest %CPU CPU Command 01时04分57秒 0 5897 100.00 0.00 0.00 100.00 1 stress 01时04分57秒 0 6159 0.00 0.20 0.00 0.20 0 watch 平均时间: UID PID %usr %system %guest %CPU CPU Command 平均时间: 0 5897 100.00 0.00 0.00 100.00 - stress 平均时间: 0 6159 0.00 0.20 0.00 0.20 - watch
从这里可以明显看到,stress 进程的 CPU 使用率为 100%。
I/O 密集型进程
注安装stress:https://snapcraft.io/install/stress-ng/centos
首先还是运行 stress 命令,但这次模拟 I/O 压力,即不停地执行 sync:
[root@master ~]# yum -y install stress-ng-0.07.29-2.el7.x86_64 [root@master ~]# stress-ng -i 1 --hdd 1 --timeout 600 stress-ng: info: [7655] dispatching hogs: 1 hdd, 1 io
还是在第二个终端运行 uptime 查看平均负载的变化情况:
Every 2.0s: uptime Thu Mar 12 01:09:36 2020 01:09:36 up 21 min, 4 users, load average: 1.11, 0.81, 0.53
然后,第三个终端运行 mpstat 查看 CPU 使用率的变化情况:
[root@master ~]# mpstat -P ALL 5 1 Linux 3.10.0-957.el7.x86_64 (master) 2020年03月12日 _x86_64_ (2 CPU) 01时30分48秒 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 01时30分53秒 all 0.20 0.00 8.01 90.29 0.00 0.20 0.00 0.00 0.00 1.30 01时30分53秒 0 0.20 0.00 9.34 90.26 0.00 0.20 0.00 0.00 0.00 0.00 01时30分53秒 1 0.20 0.00 6.84 90.14 0.00 0.00 0.00 0.00 0.00 2.82 平均时间: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 平均时间: all 0.20 0.00 8.01 90.29 0.00 0.20 0.00 0.00 0.00 1.30 平均时间: 0 0.20 0.00 9.34 90.26 0.00 0.20 0.00 0.00 0.00 0.00 平均时间: 1 0.20 0.00 6.84 90.14 0.00 0.00 0.00 0.00 0.00 2.82
查看那个进程导致的
[root@master ~]# pidstat -u 5 1 Linux 3.10.0-957.el7.x86_64 (master) 2020年03月12日 _x86_64_ (2 CPU) 01时31分42秒 UID PID %usr %system %guest %CPU CPU Command 01时31分47秒 0 9 0.00 0.20 0.00 0.20 0 rcu_sched 01时31分47秒 0 5153 0.00 1.39 0.00 1.39 0 NetworkManager 01时31分47秒 0 7537 0.00 0.20 0.00 0.20 0 kworker/0:0 01时31分47秒 0 7656 0.40 29.56 0.00 29.96 1 stress-ng-hdd 01时31分47秒 0 7657 0.00 3.97 0.00 3.97 1 stress-ng-io 01时31分47秒 0 7658 0.00 8.33 0.00 8.33 0 kworker/u4:2 01时31分47秒 0 7660 0.00 0.40 0.00 0.40 0 watch 01时31分47秒 0 7813 0.20 0.60 0.00 0.79 1 pidstat 平均时间: UID PID %usr %system %guest %CPU CPU Command 平均时间: 0 9 0.00 0.20 0.00 0.20 - rcu_sched 平均时间: 0 5153 0.00 1.39 0.00 1.39 - NetworkManager 平均时间: 0 7537 0.00 0.20 0.00 0.20 - kworker/0:0 平均时间: 0 7656 0.40 29.56 0.00 29.96 - stress-ng-hdd 平均时间: 0 7657 0.00 3.97 0.00 3.97 - stress-ng-io 平均时间: 0 7658 0.00 8.33 0.00 8.33 - kworker/u4:2 平均时间: 0 7660 0.00 0.40 0.00 0.40 - watch 平均时间: 0 7813 0.20 0.60 0.00 0.79 - pidstat
发现是stress-ng-hdd进程导致IO升高
场景三:大量进程的场景
当系统中运行进程超出 CPU 运行能力时,就会出现等待 CPU 的进程。还是使用 stress,但这次模拟的是 8 个进程:
[root@master ~]# stress -c 8 --timeout 600 stress: info: [8033] dispatching hogs: 8 cpu, 0 io, 0 vm, 0 hdd
由于系统只有 2 个 CPU,明显比 8 个进程要少得多,因而,系统的 CPU 处于严重过载状态,平均负载高达 7.97:
[root@master ~]# uptime 01:41:59 up 53 min, 4 users, load average: 7.20, 3.45, 1.92
接着再运行 pidstat 来看一下进程的情况:
[root@master ~]# pidstat -u 5 1 Linux 3.10.0-957.el7.x86_64 (master) 2020年08月24日 _x86_64_ (2 CPU) 10时10分10秒 UID PID %usr %system %guest %wait %CPU CPU Command 10时10分15秒 0 7215 24.65 0.00 0.00 74.95 24.65 1 stress 10时10分15秒 0 7216 24.85 0.00 0.00 75.15 24.85 0 stress 10时10分15秒 0 7217 24.85 0.00 0.00 74.35 24.85 1 stress 10时10分15秒 0 7218 24.85 0.00 0.00 75.15 24.85 0 stress 10时10分15秒 0 7219 24.85 0.00 0.00 74.75 24.85 0 stress 10时10分15秒 0 7220 24.85 0.00 0.00 74.55 24.85 1 stress 10时10分15秒 0 7221 24.85 0.00 0.00 74.55 24.85 0 stress 10时10分15秒 0 7222 24.85 0.00 0.00 74.75 24.85 1 stress 10时10分15秒 0 7223 0.00 0.20 0.00 0.20 0.20 0 pidstat 平均时间: UID PID %usr %system %guest %wait %CPU CPU Command 平均时间: 0 7215 24.65 0.00 0.00 74.95 24.65 - stress 平均时间: 0 7216 24.85 0.00 0.00 75.15 24.85 - stress 平均时间: 0 7217 24.85 0.00 0.00 74.35 24.85 - stress 平均时间: 0 7218 24.85 0.00 0.00 75.15 24.85 - stress 平均时间: 0 7219 24.85 0.00 0.00 74.75 24.85 - stress 平均时间: 0 7220 24.85 0.00 0.00 74.55 24.85 - stress 平均时间: 0 7221 24.85 0.00 0.00 74.55 24.85 - stress 平均时间: 0 7222 24.85 0.00 0.00 74.75 24.85 - stress 平均时间: 0 7223 0.00 0.20 0.00 0.20 0.20 - pidstat
可以看出,8 个进程在争抢 2 个 CPU,每个进程等待 CPU 的时间(也就是代码块中的 %wait 列)高达 75%。这些超出 CPU 计算能力的进程,最终导致 CPU 过载。
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:平均负载高有可能是 CPU 密集型进程导致的;平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了;当发现负载高的时候,你可以使用 mpstat、pidstat 等工具,辅助分析负载的来源。