phper-linux-gitbook/stress-sysstat-mpstat-pidstat-watch-uptime.md
2019-06-27 23:32:00 +08:00

171 lines
6.7 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 什么平均负载
简单来说,平均负载是指单位时间内,系统处于 __可运行状态__ 和 __不可中断状态__ 的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。
所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态 (Uninterruptible Sleep也称为 Disk Sleep)的进程。
比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到磁盘回复前,它是
不能被其他进程或者中断打断的,这个时候的进程就处于不可中断状态。如果此时的进程
被打断了,就容易出现磁盘数据与进程数据不一致的问题。
所以,不可中断状态实际上是系统对进程和硬件设备的一种保护机制。
因此,可以简单理解为,平均负载其实就是平均活跃进程数。平均活跃进程数,直观上
的理解就是单位时间内的活跃进程数,但它实际上是活跃进程数的指数衰减平均值。这
个“指数衰减平均”的详细含义你不用计较,这只是系统的一种更快速的计算方式,你把
它直接当成活跃进程数的平均值也没问题。
既然平均的是活跃进程数,那么最理想的,就是每个 CPU 上都刚好运行着一个进程,这样 每个 CPU 都得到了充分利用。比如当平均负载为 2 时,意味着什么呢?
- 在只有 2 个 CPU 的系统上,意味着所有的 CPU 都刚好被完全占用。
- 在 4 个 CPU 的系统上,意味着 CPU 有 50% 的空闲。
- 而在只有 1 个 CPU 的系统中,则意味着有一半的进程竞争不到 CPU。
## 平均负载为多少时合理
首先你要知道系统有几个 CPU这可以通过 top 命令或者从文件 /proc/cpuinfo 中读取,比如: `grep 'model name' /proc/cpuinfo | wc -l` 即可查看,有了 CPU 个数,我们就可以判断出,当平均负载比 CPU 个数还大的时候,系统已经出现了过载。正常平均负载高于 CPU 数量 70% 的时候,就属于负载过高。
## 平均负载与 CPU 使用率
现实工作中,我们经常容易把平均负载和 CPU 使用率混淆__平均负载是指单位时间内处于可运行状态和不可中断状态的进程数__。所以它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。比如:
CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
## 平均负载测试
以下场景在 Ubuntu 16.04 版本下进行测试配置为2 核 4 G每个场景都需要你开三个终端
#### stress 是一个 Linux 系统压力测试工具,用于异常进程模拟平均负载升高的场景
__ Ubuntu 安装__
```
apt-get install stress
```
#### sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能,其中包含以下命令
- `mpstat` 常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标, 以及所有 CPU 的平均指标
- `pidstat` 常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及 上下文切换等性能指标
__ Ubuntu 安装__
```
apt-get install sysstat
```
#### 场景一CPU 密集型进程
第一个终端输入
```
stress --cpu 1 --timeout 600 #模拟一个 CPU 使用率 100%
```
第二个终端输入
```
watch -d uptime #监测系统运行时间 -d 表示高亮显示变化的区域
```
第三个终端输入
```
mpstat -P ALL 5 #-P ALL 表示监控所有 CPU后面数字 5 表示间隔 5 秒后输出一组数据
pidstat -u 5 1 #间隔 5 秒后输出一组数据
```
结果
```
Linux 4.4.0-142-generic (10-53-166-171) 06/26/2019 _x86_64_ (2 CPU)
10:24:14 PM UID PID %usr %system %guest %CPU CPU Command
10:24:19 PM 113 4606 0.20 0.00 0.00 0.20 0 beam.smp
10:24:19 PM 1000 15703 100.00 0.00 0.00 100.00 1 stress
10:24:19 PM 1000 15789 0.20 0.00 0.00 0.20 0 watch
```
#### 场景二I/O 密集型进程
第一个终端输入
```
stress -i 1 --timeout 600 #模拟 I/O 压力
```
第二个终端输入
```
watch -d uptime #监测系统运行时间 -d 表示高亮显示变化的区域
```
第三个终端输入
```
mpstat -P ALL 5 #-P ALL 表示监控所有 CPU后面数字 5 表示间隔 5 秒后输出一组数据
pidstat -u 5 1 #间隔 5 秒后输出一组数据
```
结果
```
Linux 4.4.0-142-generic (10-53-166-171) 06/26/2019 _x86_64_ (2 CPU)
10:28:28 PM UID PID %usr %system %guest %CPU CPU Command
10:28:33 PM 113 4606 0.40 0.00 0.00 0.40 0 beam.smp
10:28:33 PM 1000 16182 0.20 100.00 0.00 100.20 1 stress
10:28:33 PM 1000 16185 0.00 0.20 0.00 0.20 0 watch
10:28:33 PM 1000 16495 0.00 0.20 0.00 0.20 0 pidstat
```
#### 场景三:大量进程的场景
第一个终端输入
```
stress -c 8 --timeout 600 #模拟 8 个进程
```
第二个终端输入
```
watch -d uptime #监测系统运行时间 -d 表示高亮显示变化的区域
```
第三个终端输入
```
mpstat -P ALL 5 #-P ALL 表示监控所有 CPU后面数字 5 表示间隔 5 秒后输出一组数据
pidstat -u 5 1 #间隔 5 秒后输出一组数据
```
结果
```
Linux 4.4.0-142-generic (10-53-166-171) 06/26/2019 _x86_64_ (2 CPU)
10:30:59 PM UID PID %usr %system %guest %CPU CPU Command
10:31:04 PM 113 4606 0.20 0.00 0.00 0.20 0 beam.smp
10:31:04 PM 1000 16825 24.90 0.00 0.00 24.90 1 stress
10:31:04 PM 1000 16826 24.70 0.00 0.00 24.70 0 stress
10:31:04 PM 1000 16827 24.70 0.00 0.00 24.70 1 stress
10:31:04 PM 1000 16828 24.70 0.00 0.00 24.70 1 stress
10:31:04 PM 1000 16829 24.70 0.00 0.00 24.70 1 stress
10:31:04 PM 1000 16830 24.90 0.00 0.00 24.90 0 stress
10:31:04 PM 1000 16831 24.70 0.00 0.00 24.70 0 stress
10:31:04 PM 1000 16832 24.70 0.00 0.00 24.70 0 stress
10:31:04 PM 1000 16884 0.20 0.00 0.00 0.20 0 pidstat
```