01 uptime 命令
通常我们发现系统变慢时,我们都会执行 top 或者 uptime 命令,来查看当前系统的负载情况,比如像下面,我执行了 uptime,系统返回的了结果。
[root@lincoding ~]# uptime
08:31:49 up 27 min, 1 user, load average: 0.07, 0.04, 0.00
前几列的信息,相信大家都很熟悉,它们分别是当前时间、系统运行时间和正在登陆的用户个数,最后一个就是系统平均负载的情况。
08:31:49 // 当前时间
up 27 min // 系统运行时间
1 user // 正在登录用户数
load average: 0.07, 0.04, 0.00 // 平均负载的情况
Load Average 的三个数字,依次则是 过去 1 分钟、5 分钟、15 分钟的平均负载。可以通过观察这三个数字的大小,可以简单判断系统的负载是下降的趋势还是上升的趋势。
- 如果
load average: 1.00, 5.00, 10.00
三个数字依次 增大 ,则说明在过去的 1 分钟系统的负载比过去 15 分钟系统的负载 小,表明系统的负载是 下降 的趋势。 - 如果
load average: 10.00, 5.00, 1.00
三个数字依次 降低 ,则说明在过去的 1 分钟系统的负载比过去 15 分钟系统的负载 大,表明系统的负载是 上升 的趋势。 - 如果
load average: 0.07, 0.04, 0.0
三个数字基本相同,或者相差不大,表明系统的负载是平稳的。
所以分析系统的负载情况,必须要看三个不同时间间隔的平均值。
02 平均负载概念
平均负载很多人容易理解成单位时间内的 CPU 使用率,这是不正确的。平均负载确实与 CPU 使用率有关系,但不是直接的关系。
简单来说,平均负载是指单位时间内,系统处于 可运行状态 和不可中断状态 的平均进程数,也就是 平均活跃进程数,它和 CPU 使用率并没有直接关系。
- 可运行状态,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是在 ps 命令看到的 R 状态的进程。
- 不可中断状态,是指正处于内核关键流程中的进程,并且这些流程是不可以打断的,比如最常见的等待硬件设备的 I/O 响应,也就是在 ps 命令看到的 D 状态的进程。
因此,平均负载其实就是平均活跃进程数,可以更直观的理解成单位时间内的活跃进程数。
既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上刚好运行着一个进程,这样每个 CPU 就得到了充分利用。
比如当平均负载为 2 时,意味着:
- 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
- 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
- 在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。
03 平均负载为多少时合理
在评判你当前的系统平均负载是否合理的时,首先你要知道系统有几个 CPU,可以通过 lscpu 命令或者从文件 /proc/cpuinfo 中读取
# lscpu 命令查看 CPU 个数
[root@lincoding ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 4 # 这里数字表示 CPU 个数
....
# 从文件 /proc/cpuinfo 中查看 CPU 个数
[root@lincoding ~]# grep 'model name' /proc/cpuinfo | wc -l
4
有了 CPU 个数,我们就可以判断出,当平均负载比 CPU 个数还大的时候,系统已经出现了过载。
这里我再举个例子,假设我们在一个单 CPU 系统上看到平均负载为 1.73,0.60,7.98
- 在过去 1 分钟内,系统有 73% 的超载
- 在过 15 分钟内,有 698% 的超载,从整体趋势来看,系统的负载在降低。
平均负载高于 CPU 数量 70% 的时候,就应该分析排查负载高的问题了。一旦负载过高,就可能导致进程响应变慢,进而影响服务的正常功能。
04 平均负载与 CPU 使用率
我们经常容易把平均负载和 CPU 使用率混淆,所以在这里,我也做一个区分。
再次说明下,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了 正在使用 CPU 的进程,还包括 等待 CPU 和 等待 I/O 的进程。
而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
05 平均负载升高分析命令
我们现在很清楚的知道导致平均负载高的情况,不只是看 CPU 的使用率,也要观察系统 I/O 等待时间高不高。
当发现平均负载升高时,可以使用 mpstat
命令查看 CPU 的性能。
# -P ALL 表示监控所有 CPU,后面数字 1 表示间隔 1 秒后输出一组数据
$ mpstat -P ALL 1
Linux 2.6.32-431.el6.x86_64 (lzc) 11/05/2019 _x86_64_ (2 CPU)
07:51:45 PM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle
07:51:50 PM all 42.90 0.00 49.39 0.41 0.00 4.56 0.00 0.00 2.74
07:51:50 PM 0 44.38 0.00 48.67 0.41 0.00 2.86 0.00 0.00 3.68
07:51:50 PM 1 41.57 0.00 49.80 0.40 0.00 6.43 0.00 0.00 1.81
从上面发现
- CPU 的用户层(%usr)使用率高达 45% 左右;
- CPU 的系统层(%sys)使用率高达 50% 左右;
- CPU 的 I/0 – 等待(%iowait)占用率为 0.41%;
- CPU 的空闲率(%idle)只有 2~3%。
可以推断出是由于 CPU 使用率导致平均负载升高的情况。
假设只有 CPU 的 I /0 等待(%iowait)占用率高,CPU 用户层和系统层使用率很轻松,那么导致平均负载升高的原因就是 iowait 的升高。
判断了是因为 CPU 使用率升高还是 iowait 升高导致平均负载升高后,我们还需要定位是哪个进程导致的。可以用 pidstat
来查询:
# 间隔 1 秒后输出一组数据,- u 表示 CPU 指标
$ pidstat -u 1
08:07:55 PM PID %usr %system %guest %CPU CPU Command
08:07:56 PM 4 0.00 1.00 0.00 1.00 0 ksoftirqd/0
08:07:56 PM 9 0.00 1.00 0.00 1.00 1 ksoftirqd/1
08:07:56 PM 11 0.00 16.00 0.00 16.00 0 events/0
08:07:56 PM 12 0.00 20.00 0.00 20.00 1 events/1
08:07:56 PM 616 7.00 6.00 0.00 13.00 1 pppoe
08:07:56 PM 2745 6.00 6.00 0.00 12.00 1 pppoe
可以发现是 events/0
和 events/1
内核进程 CPU 使用率非常高,所以可能这两个进程导致平均负载升高。
06 小结
平均负载提供了一个快速查看系统整体性能的手段,反映了整体的负载情况。但只看平均负载本身,我们并不能直接发现,到底是哪里出现了瓶颈。所以,在理解平均负载时,也要注意:
- 平均负载高有可能是 CPU 密集型进程导致的;
- 平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了;
- 当发现负载高的时候,你可以使用
mpstat
、pidstat
等工具,辅助分析负载的来源。