到底应该怎么理解“平均负载”?
CPU性能工具
平均负载概念
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数。
所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。
平均负载为多少时合理
查看CPU个数
可以用
grep 'model name' /proc/cpuinfo | wc -l
或用
htop
查看系统负载
uptime
输出:
09:00:03 up 364 days, 13:57, 0 users, load average: 0.47, 0.11, 0.03
- 09:00:03:当前时间
- up 364 days, 13:57:系统运行时间
- 0 users:登录用户数
- load average: 0.47, 0.11, 0.03:系统1分钟、5分钟、15分钟负载为 0.47, 0.11, 0.03
当平均负载高于 CPU 数量 70% 的时候,就需要注意了。
这里有2个CPU,只要负载不超过1.4就说明是OK的。
平均负载与 CPU 使用率
平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。所以,它不仅包括了正在使用 CPU 的进程,还包括等待 CPU 和等待 I/O 的进程。
而 CPU 使用率,是单位时间内 CPU 繁忙情况的统计,跟平均负载并不一定完全对应。
比如:
- CPU 密集型进程,使用大量 CPU 会导致平均负载升高,此时这两者是一致的;
- I/O 密集型进程,等待 I/O 也会导致平均负载升高,但 CPU 使用率不一定很高;
- 大量等待 CPU 的进程调度也会导致平均负载升高,此时的 CPU 使用率也会比较高。
确认平均负载升高原因
1. 用 uptime 查看平均负载
# -d 参数表示高亮显示变化的区域
watch -d uptime
# 09:42:36 up 364 days, 14:40, 0 users, load average: 1.07, 0.76, 0.34
2. 用 mpstat 查看 CPU 使用率
CPU密集型
# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
mpstat -P ALL 5
09:43:17 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
09:43:22 AM all 51.15 0.00 1.10 0.20 0.00 0.00 0.00 0.00 0.00 47.55
09:43:22 AM 0 2.20 0.00 2.40 0.60 0.00 0.00 0.00 0.00 0.00 94.80
09:43:22 AM 1 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
# 上面的输出其他指标都很低,只有CPU很高,这个表明是CPU密集型
IO密集型
# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
mpstat -P ALL 5
09:52:55 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
09:53:00 AM all 1.80 0.00 9.93 5.17 0.00 0.21 0.00 0.00 0.00 82.89
09:53:00 AM 0 1.94 0.00 3.66 9.25 0.00 0.43 0.00 0.00 0.00 84.73
09:53:00 AM 1 1.86 0.00 15.88 1.44 0.00 0.21 0.00 0.00 0.00 80.62
# 上面的输出其他指标都很低,只有iowait高,这个表明是IO密集型
大量进程
# -P ALL 表示监控所有CPU,后面数字5表示间隔5秒后输出一组数据
mpstat -P ALL 5
Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle
Average: all 98.95 0.00 1.05 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: 0 99.00 0.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
Average: 1 98.90 0.00 1.10 0.00 0.00 0.00 0.00 0.00 0.00 0.00
# 上面的输出表明所有CPU占用都高,可能有大量进程,需要进一步判断
3. 用 pidstat 确认哪一个进程导致 CPU 100%
CPU密集型
# 间隔5秒后输出一组数据,pidstat [option] interval [count] -u 默认的参数,显示各个进行的CPU使用统计 5代表每5秒采样一次,1代表一共采样1次
pidstat -u 5 1
09:45:48 AM UID PID %usr %system %guest %wait %CPU CPU Command
09:45:53 AM 500 9951 0.20 0.20 0.00 0.00 0.40 0 node
09:45:53 AM 500 9995 0.40 0.40 0.00 0.20 0.80 0 node
09:45:53 AM 500 10042 0.20 0.00 0.00 0.00 0.20 0 node
09:45:53 AM 0 11399 0.60 0.20 0.00 0.00 0.80 0 YDService
09:45:53 AM 500 24061 100.00 0.00 0.00 0.00 100.00 1 stress
09:45:53 AM 0 30257 0.40 0.20 0.00 0.00 0.60 0 barad_agent
# 这里可以看到是 stress 的CPU占用很高
IO密集型
# 间隔5秒后输出一组数据,pidstat [option] interval [count] -u 默认的参数,显示各个进行的CPU使用统计 5代表每5秒采样一次,1代表一共采样1次
pidstat -u 5 1
10:02:15 AM UID PID %usr %system %guest %wait %CPU CPU Command
10:02:20 AM 0 7 0.00 0.20 0.00 0.00 0.20 0 ksoftirqd/0
10:02:20 AM 0 8 0.00 0.20 0.00 0.00 0.20 0 rcu_sched
10:02:20 AM 0 310 0.00 4.19 0.00 0.00 4.19 1 kworker/1:1H
10:02:20 AM 0 398 0.00 0.60 0.00 0.00 0.60 0 kworker/0:1H
10:02:20 AM 500 8278 1.00 18.76 0.00 5.59 19.76 1 stress
10:02:20 AM 500 8467 0.00 0.20 0.00 0.00 0.20 0 pidstat
10:02:20 AM 500 9951 0.00 0.20 0.00 0.00 0.20 1 node
10:02:20 AM 500 9995 0.20 0.40 0.00 0.00 0.60 1 node
10:02:20 AM 500 10035 0.20 0.00 0.00 0.00 0.20 0 node
10:02:20 AM 500 10042 0.00 0.20 0.00 0.00 0.20 0 node
10:02:20 AM 0 11399 1.00 0.40 0.00 0.00 1.40 0 YDService
10:02:20 AM 500 24418 0.20 0.00 0.00 0.00 0.20 0 watch
10:02:20 AM 113 26499 0.20 0.20 0.00 0.00 0.40 0 mysqld
10:02:20 AM 0 30256 0.00 0.20 0.00 0.00 0.20 1 barad_agent
10:02:20 AM 0 30257 0.60 0.40 0.00 0.00 1.00 1 barad_agent
# 这里可以看到是 stress 的wait高
大量进程
# 间隔5秒后输出一组数据,pidstat [option] interval [count] -u 默认的参数,显示各个进行的CPU使用统计 5代表每5秒采样一次,1代表一共采样1次
pidstat -u 5 1
10:13:28 AM UID PID %usr %system %guest %wait %CPU CPU Command
10:13:33 AM 33 4706 0.60 0.00 0.00 0.20 0.60 0 apache2
10:13:33 AM 500 9995 0.20 0.60 0.00 0.00 0.79 1 node
10:13:33 AM 500 10042 0.20 0.00 0.00 0.00 0.20 0 node
10:13:33 AM 0 11399 0.20 0.60 0.00 0.00 0.79 0 YDService
10:13:33 AM 500 14543 24.01 0.00 0.00 75.40 24.01 0 stress
10:13:33 AM 500 14544 23.61 0.00 0.00 75.60 23.61 1 stress
10:13:33 AM 500 14545 24.01 0.00 0.00 75.60 24.01 1 stress
10:13:33 AM 500 14546 24.01 0.00 0.00 75.40 24.01 1 stress
10:13:33 AM 500 14547 23.81 0.00 0.00 75.00 23.81 0 stress
10:13:33 AM 500 14548 24.21 0.00 0.00 75.20 24.21 1 stress
10:13:33 AM 500 14549 24.21 0.00 0.00 75.20 24.21 0 stress
10:13:33 AM 500 14550 24.01 0.20 0.00 75.20 24.21 0 stress
10:13:33 AM 500 14765 0.00 0.20 0.00 0.00 0.20 0 pidstat
10:13:33 AM 500 24418 0.00 0.20 0.00 0.00 0.20 0 watch
10:13:33 AM 113 26499 0.20 0.00 0.00 0.00 0.20 1 mysqld
10:13:33 AM 0 30256 0.20 0.00 0.00 0.00 0.20 0 barad_agent
10:13:33 AM 0 30257 0.40 0.60 0.00 0.00 0.99 0 barad_agent
# 这里可以看到是8个 stress 进程抢2个CPU
辅助工具
sysstat
而 sysstat 包含了常用的 Linux 性能工具,用来监控和分析系统的性能。
这个包有两个命令 mpstat 和 pidstat。
- mpstat 是一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以及所有 CPU 的平均指标。
- pidstat 是一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上下文切换等性能指标。
stress
stress 是一个 Linux 系统压力测试工具,可以用作异常进程模拟平均负载升高的场景
# 模拟1个 CPU 使用率 100% 的场景
stress --cpu 1 --timeout 600
# 模拟1个 IO 使用率 100% 的场景
stress -i 1 --timeout 600
# 模拟8个进程的场景
stress -c 8 --timeout 600