Load Average 详解

转自:http://bbs.uplinux.com/viewthread.php?tid=10424

Linux中的“load average“到底是什么意思
执行top,w,uptime,在最上一行,均能得到类似下面的一行:

21:25:38 up 59 min,  2 users,  load average: 0.33, 0.40, 0.38

前面的值还是比较好理解,但是这个load average就不太好理解了,虽然知道是平均负载,但是它到底意味着什么?
什么样的负载是正常的,什么样的负载表示系统负荷高?
man uptime显然是最快捷的办法,得到的解释如下:

uptime  gives  a  one  line display of the following information.  The current time, how long the system has been running, how many users are currently  logged  on, and the system load averages for the past 1, 5, and 15 minutes.

解释很明确,但是还是不知道什么是平均负载。显然需要祭出google大刀了。
google一把,分别得到了下面的解释
中文的很多解释如下

系统平均负载被定义为在特定时间间隔内运行队列中的平均进程树。如果一个进程满足以下条件则其就会位于运行队列中:
– 它没有在等待I/O操作的结果
– 它没有主动进入等待状态(也就是没有调用’wait’)
– 没有被停止(例如:等待终止)

例如:

[root@www2 init.d]# uptime
7:51pm up 2 days, 5:43, 2 users, load average: 8.13, 5.90, 4.94

命令输出的最后内容表示在过去的1、5、15分钟内运行队列中的平均进程数量。
一般来说只要每个CPU的当前活动进程数不大于3那么系统的性能就是良好的,如果每个CPU的任务数大于5,那么就表示这台机器的性能有严重问题。对于上面的例子来说,假设系统有两个CPU,那么其每个CPU的当前任务数为:8.13/2=4.065。这表示该系统的性能是可以接受的。
而且还说这个值会接近1,这显然不对,我今天就看到了负载超过50的。
AIX系统中给出解释是

The uptime command prints the current time, the length of time the system has been up, the number of users online, and the load average. The load average is the number of runnable processes over the preceding 5-, 10-, 15-minute intervals.

比Linux还一点的是给出了一个可运行的进程,不过还是不很明确,继续
《UNIX Power Tools》一书中给出的解释是

The load average tries to measure the number of active processes at any time. As a measure of CPU utilization, the load average is simplistic, poorly defined, but far from useless.

不知道这里的“active processes"和AIX中的"runnable processes"是什么关系,我想不应该等同吧。还得继续
这本书继续写道

What’s high? … Ideally, you’d like a load average under,say, 3, … Ultimately, ‘high’ means high enough so that you don’t need uptime to tell you that the system is overloaded. …
different systems will behave differently under the same load average.
… running a single cpu-bound background job can bring response to a crawl even though the load avg
remains quite low.

这里说的3是什么意思?又是从哪里来的,他的3指的平均负载中的哪个呢,1分钟的?5分钟的?还是15分钟的?
不得而知,继续找找,看看有没有更详细的解答
在《Sun Performance and Tuning》一书的“Understanding and Using the Load Average”一节中,作者这样写道

The load average is the sum of the run queue length and the number of jobs currently running on the CPUs. In Solaris 2.0 and 2.2 the load average did not include the running jobs but this bug was fixed in Solaris 2.3.

这里提到了运行队列(run queue),那么如何理解run queue,runnable processes和active processes三者的关系,是他们的平均值还是其和呢?
现在要做的就是去“Read The Fucking Source Code"了。
uptime这类程序属于procps包,拿到源代码,现看uptime.c,很简单就是下面几行

#include <stdio.h>
#include <string.h>
#include "proc/whattime.h"
#include "proc/version.h"
int main(int argc, char *argv[]) {
    if(argc == 1) {
        print_uptime();
        return 0;
    }
    if((argc == 2) && (!strcmp(argv[1], "-V"))) {
        display_version();
        return 0;
    }
    fprintf(stderr, "usage: uptime [-V]\n    -V    display version\n");
    return 1;
}

而whattime.h的中代码是

#ifndef PROC_WHATTIME_H
#define PROC_WHATTIME_H
 
#include "procps.h"
 
EXTERN_C_BEGIN
 
extern void print_uptime(void);
extern char *sprint_uptime(void);
 
EXTERN_C_END
 
#endif

如此顺藤摸瓜,找到了实际函数所在地include/linux/sched.h,他定义了一个宏

#define FSHIFT      11      /* nr of bits of precision */
 #define FIXED_1     (1<<FSHIFT) /* 1.0 as fixed-point */
 #define LOAD_FREQ   (5*HZ)      /* 5 sec intervals */
 #define EXP_1       1884        /* 1/exp(5sec/1min) as fixed-point */
 #define EXP_5       2014        /* 1/exp(5sec/5min) */
 #define EXP_15      2037        /* 1/exp(5sec/15min) */
 
 #define CALC_LOAD(load,exp,n) \
  load *= exp; \
  load += n*(FIXED_1-exp); \
  load >>= FSHIFT;

有两个疑惑

1)常量的那些值如何来的?

2)CALC_LOAD到底想做什么?

这个宏可以用下面的数学表达式描述

load(t) = load(t ? 1) e^(? 5/60m )+ n(t) (1 ? e^(? 5/60m ))

其中:


m = 1, 5, 15 表示经过的时间

load(t) 表示现在的负载

load(t ? 1) 表示上一次时间的负载

n(t) 表示当前活动进程(active processes)的数目。

暂时我只能分析到这里了,再分析我头大了,有时间再分析吧。

到此,只是知道负载的计算与进程有关,但是到底值的大小如何具体衡量系统负载还是未知数

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据