在排查性能问题的时候,我们经常会使用 top 或者 uptime 两个 Linux 命令,top 命令和 uptime 命令都会给出最近机器 1 min,5 min,15 min 的平均负载情况,一般平均负载值(Average Load)接近甚至超出 CPU cores (现在一般指 processors 的个数, 现在 CPU 的一个 core 一般有两个 processor, 可以处理两个进程) 时,系统会有性能瓶颈.
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程.
造成平均负载升高的原因一般有以下几种:
- 1、有 IO Bound 进程(即存在 IO 密集型任务)
- 2、有 CPU Bound 进程(即存在 CPU 密集型任务)
- 3、处于就绪状态(Ready)的进程多
- …..
本篇文章主要记录下造成平均负载升高的两个场景. IO 密集型场景和 CPU 密集型场景.
这里的实验环境在一个操作系统为 Ubuntu 20.04.3 LTS 的容器内, 通过 stress 进行 IO Bound 与 CPU Bound 场景的模拟, 宿主机有 16 个 processors, 8G 运行内存.
1 | docker run --rm -it ubuntu:latest |
1 | root@bfdbc798879c:/# top |
让我们先安装一下 stress 压力测试工具和系统观测要用到的工具.
1 | apt-get update |
CPU Bound 场景
这里我们让三个逻辑 CPU 满载:
1 | # 持续 10 min, 3 CPU 满载 |
我们用 watch 命令持续观察平均负载情况, 平均负载在逐渐变高,此时我的电脑 CPU 风扇也很响了😂
1 | watch -d uptime |
我们在使用 top 命令可以看到有三个 CPU 已经满载了,使用率百分百,还可以看到是哪个 COMMMAND 造成的,
但是上面不能很清楚的看到 IO 的情况,接下来我们用 mpstat 每隔 5 秒将所有 CPU 的观测情况打出来:
1 | mpstat -P ALL 5 |
可以很清楚的看到,的确有三个 CPU 的空闲状态为 0(满载),使用率百分百,且 IO Wait 等待时间是很低的,所以单单 CPU Bound 场景可造成 Average Load 的升高.
不使用 top 命令,使用 pidstat 每隔 5 秒, 三次打印进程的 CPU 情况可定位出是哪个进程造成的平均负载升高.
1 | root@bfdbc798879c:/# pidstat -u 5 3 |
IO Bound 场景
stress 压力工具也可以方便的进行 IO Bound 场景的模拟,
开始之前将上面 CPU Bound 场景给终止, 同样地, 我们先开好一个 Terminal 观察平均负载的变化:
1 | watch -d uptime |
使用 strees 调起 50 个进程(这里要高于 CPU processors 的数量, 让进程争夺 CPU), 不断打 IO, 持续 10 min:
1 | root@bfdbc798879c:/# stress -i 50 -t 600 |
可以观察到, 平均负载在不断升高, 再使用 mpstat 可以观测到 IO Wait 很高.
1 | mpstat -P ALL 5 |
可以 GET 到 IO Bound 任务的确会造成平均负载升高, 结合 iostat, 我们还可以观测磁盘设备的读写性能情况:
1 | iostat -d -x |