剑客
关注科技互联网

理解LOAD

load是Linux系统上常用的指标, 这里从原理上分析一下.

首先, load信息从哪里来?

linux上的常用命令如 uptime
, top
等都可以显示系统load, 其实现都是从虚拟文件 /proc/loadavg
读取数据, 所以这里我们直接看 /proc/loadavg
的内容:

$ cat /proc/loadavg 
0.29 0.25 0.28 1/553 18329

RTFM(man proc
), 可以知道这几个数字的含义:

The first three fields in this file are load average figures giving the number of jobs in the run queue (state R) or waiting for disk I/O (state D) averaged over 1, 5, and 15 minutes.

The fourth field consists of two numbers separated by a slash (/). The first of these is the number of currently runnable kernel scheduling entities (processes, threads). The value after the slash is the number of kernel scheduling entities that currently exist on the system. The fifth field is the PID of the process that was most recently created on the system.

后面三项比较容易理解, 分别是:

  • 当前可运行的任务数, 如果这个值远远超过cpu数目, 说明很多任务在run queue等待

  • 当前线程数(等于 ps -eL|wc -l
    )

  • 最近创建的进程PID

前面三项是我们通过 uptime
命令看到的, 分别是最近1分钟,5分钟和15分钟的 load
, 也就是处在R或者D状态的任务数.

当我们看到服务器上的load很高, 首先要分析这些任务是在R状态还是D状态. R(running)
表示可运行, 即该任务在run queue(教科书上好像称为 ready
状态, 在linux kernel中都称成为 running
)中(但一个cpu上某个时刻只有一个任务在真正运行), D (disk sleeping)
表示任务在sleep状态而且无法被其他任务异步唤起, 也就是说, 不处理signal.

举几个实践中的例子:

  • 如果有两个任务dead loop, 那么load一定会大于1

  • 如果多个任务都在等待磁盘操作完成,但是底层磁盘驱动因为某些原因无法唤起这些任务,那么LOAD会很高, 但CPU使用率却很低, 而且无法KILL这些进程.

所以, 简单的说, load高说明等待的任务较多, 但是这些任务有可能在等待CPU来运行, 也有可能在等待内核发起的其他事件(比如IO密集型应用在等待磁盘操作).

了解了这些, 可以进一步研究LOAD数据究竟是如何统计的.

一个最直接的方式就是用一个数组记录采样, 然后根据1/5/15分钟计算出平均值, 即moving average. 但这样每次计算sum都需要增加一个新值, drop一个旧值, 而且会占用较多的存储空间.

linux内核的实现则采用了EMA(exponential moving average)算法, 只根据上次的平均值和当前值来计算最新的平均值, 最新的采样会比旧采样有更高的权重. 具体算法见内核代码 kernel/sched/loadavg.c 

那么, 问题来了, 说 1/5/15分钟的LOAD是不是在骗我们? 因为从计算过程来看, 这些值其实是根据所有的历史数据计算出来的! 但是, 历史数据的权重会指数级衰减(decay exponentially). wikipedia的数据:

1-minute load average will add up 63% (more precisely: 1 – 1/e) of the load from last minute, plus 37% (1/e) of the load since start up excluding the last minute.

Hope it helps.

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址