top命令中load average显示的是最近1分钟、5分钟和15分钟的系统平均负载。系统平均负载不仅包括正在运行的任务还包括处于不可中断状态(TASK_UNINTERRUPTIBLE 或 nr_uninterruptible)的任务数。
一、理解Linux平均负载
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的任务数(CPU、磁盘、不间断锁),它和 CPU使用率没有直接的关系。
可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态的进程,可以这么理解:
- 这个进程现在基本上不在 CPU 执行指令,但是它还是占用这个 CPU。
- 这个进程在做一些事情(大部分是磁盘 I/O),做的这个事情不能被打断。
- 为啥不能被打断,因为系统觉得它做的这个事情很重要,如果打断了可能结果很严重(比如进程正在读写磁盘数据,把它打断了可能会导致进程的数据和磁盘上的数据不一致的情况)。
CPU使用率和CPU平均负载容易混淆,CPU使用率表示单位时间CPU的利用情况,CPU使用率和平均负载的关系有三个场景:
- CPU密集型进程,大量使用CPU会使CPU利用率和平均负载都增高。
- IO密集型进程,会使平均负载增高但CPU使用率不一定会增高。
- 大量等待CPU的进程调度会使平均负载增高,CPU使用率也会增高。
二、平均负载多少算合适
对于 CPU 负载平均值,您可以将该值除以 CPU 核数,通常会觉得该值大于或等于 1,说明系统处于饱和状态,可能会导致性能问题。然而loadavg 的计算不仅包括 R 进程,还包括 D 进程,这类的进程又不能简单的除以 CPU 核数。同时,loadavg 的计算总是一段时间内的(至少间隔 1min)。虽然它用了指数加权平均,但是还是无法精确地展现现在的状态。
所以针对系统负载并不能单一地依靠 loadavg 来判断,要结合其他的系统性能指标一起来看。
至于Linux的系统负载平均值:由于它们涵盖不同的资源类型,因此更加模糊,并没有一个绝对的 loadavg/cpu 核数的比值(比如 0.7)可以指导用户当前是否有性能问题,重要的还是看趋势相对比较更有用,比如你知道系统在负载为20时运行良好,而现在是40时,那么是时候深入研究其他指标了,看看发生了什么。
三、更好的参考指标
当Linux平均负载增加时,我们知道对资源(CPU、磁盘和一些锁)的需求会增加,但不确定是哪一个,可以用如下指标进行排查
- 每个CPU的利用率
# mpstat -P ALL 1
- 每个进程的 CPU 利用率
# top
# pidstat 1
- CPU 运行队列长度
# vmstat 1
四、负载高排查思路
进程增多可能会导致系统负载上升,但是进程不变情况下,负载突然飙升,那就是线程增长所引起的,可以使用如下脚本进行排查。原理是当系统当前loadavg超过一个预设值时,周期采样当前的R,D状态线程,通过这个信息来确定load产生的原因
# cat loadavg.sh
#!/bin/bash
# D TASK_UNINTERRUPTIBLE 不可中断的睡眠状态
# R TASK_RUNNING 正在运行的和准备就绪等待运行的进程(running & runnable)
while true; do
load=$(cat /proc/loadavg | awk '$1 > 20 {print $1}')
if [ -n "$load" ]; then
ps -Leo stat,pid,ppid,command | awk 'index($1, "D") || index($1, "R")'
fi
sleep 1
done
# sh loadavg.sh >> /tmp/loadavg.log
Reference