linux主机load average的概念计算过程注意事项
最近开发的一个模块需要根据机房各节点的负载情况(如网卡IO、load average等指标)做任务调度,刚开始对Linux机器load average这项指标不是很清楚,经过调研,终于搞清楚了其计算方法和影响因素,作为笔记,记录于此。
1. load average
当在shell终端键入top命令时,默认情况下,在输出内容的第一行会有load average这项指标值,如下所示:
top - 19:10:32 up 626 days, 4:58, 1 user, load average: 7.74, 5.62, 6.51
Tasks: 181 total, 8 running, 173 sleeping, 0 stopped, 0 zombie
Cpu(s): 4.0% us, 0.5% sy, 0.0% ni, 95.4% id, 0.0% wa, 0.0% hi, 0.0% si
同样,输入uptime命令,load average也会被输出:
19:15:10 up 129 days, 5:12, 15 users, load average: 0.01, 0.09, 0.05
根据man uptime的说明可知, load average包含的3个值分别表示past 1, 5 and 15 minutes内的系统平均负载。
那么,这3个值是怎么计算出来的?下面从Linux源码中寻找答案。
2. linux机器load average的计算过程
wikipedia在对load的解释( 参见这里)中,提到了linux系统对load的计算方法,为亲自验证,我check了linux源码(linux kernel 2.6.9)中的相关代码,自顶向下的验证过程如下。
在源码树kernel/timer.c文件中,计算系统load的函数代码如下:
// 源码树路径:kernel/timer.c
/** Hmm.. Changed this, as the GNU make sources (load.c) seems to* imply that avenrun[] is the standard name for this kind of thing.* Nothing else seems to be standardized: the fractional size etc* all seem to differ on different machines.** Requires xtime_lock to access.*/
unsigned long avenrun[3];/** calc_load - given tick count, update the avenrun load estimates.* This is called while holding a write_lock on xtime_lock.*/
static inline void calc_load(unsigned long ticks)
{unsigned long active_tasks; /* fixed-point */static int count = LOAD_FREQ;count -= ticks;if (count < 0) {count += LOAD_FREQ;active_tasks = count_active_tasks();CALC_LOAD(avenrun[0], EXP_1, active_tasks);CALC_LOAD(avenrun[1], EXP_5, active_tasks);CALC_LOAD(avenrun[2], EXP_15, active_tasks);}
}
从上面的代码可知,定义的数组avenrun[]包含3个元素,分别用于存放past 1, 5 and 15 minutes的load average值。calc_load则是具体的计算函数,其参数ticks表示采样间隔。函数体中,获取当前的活跃进程数(active tasks),然后以其为参数,调用CALC_LOAD分别计算3种load average。
沿着函数调用链,可以看到count_active_tasks()定义如下(也在kernel/timer.c文件中):
/* * Nr of active tasks - counted in fixed-point numbers*/
static unsigned long count_active_tasks(void)
{return (nr_running() + nr_uninterruptible()) * FIXED_1;
}
由源码可见,count_active_tasks()返回当前的活跃进程数,其中活跃进程包括:1)当前正在运行的进程(nr_running);2)不可中断的sleeping进程(如正在执行IO操作的被挂起进程)。
关于nr_running进程和nr_uninterruptible进程的计算方法,可以在源码树kernel/schde.c中看到相关代码:
// 源码树路径:kernel/sched.c
/** nr_running, nr_uninterruptible and nr_context_switches:** externally visible scheduler statistics: current number of runnable* threads, current number of uninterruptible-sleeping threads, total* number of context switches performed since bootup.*/
unsigned long nr_running(void)
{unsigned long i, sum = 0;for (i = 0; i < NR_CPUS; i++)sum += cpu_rq(i)->nr_running;return sum;
}unsigned long nr_uninterruptible(void)
{unsigned long i, sum = 0;for_each_cpu(i)sum += cpu_rq(i)->nr_uninterruptible;return sum;
}
继续沿着函数调用链查看,可在include/linux/sched.h中看到CALC_LOAD的定义:
// 源码树路径:include/linux/sched.h
/** These are the constant used to fake the fixed-point load-average* counting. Some notes:* - 11 bit fractions expand to 22 bits by the multiplies: this gives* a load-average precision of 10 bits integer + 11 bits fractional* - if you want to count load-averages more often, you need more* precision, or rounding will get you. With 2-second counting freq,* the EXP_n values would be 1981, 2034 and 2043 if still using only* 11 bit fractions.*/
extern unsigned long avenrun[]; /* Load averages */#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;
可以看到,CALC_LOAD是一个宏定义,load average的值与3个参数相关,但若只考虑某1项指标值(如past 5 minutes的load average),则该值只受当前活跃进程数(active tasks)的影响,而活跃进程数包括两种:当前正在运行的进程和不可中断的挂起进程。
这符合我的观察结果:三台硬件配置相同的linux机器(8 cup, 16GB memory, 1.8T disk),在当前总进程数相差不多(均为170+)的情况下,其中1台机器有1个普通进程(这里的"普通"是指既非CPU型又非IO型)在运行,其余均sleeping;第2台机器有5个cpu型进程,cpu占用率均达到99%,其余进程sleeping;第3台机器2个进程读写硬盘,其余sleeping。很明显地可以看到:第3台机器的load average指标的3个值均为最大,第2台机器次之,第1台机器的3个值均接近0。
由此,还可以推断出:与running类型的进程相比,uninterruptible类型的进程(如正在进行IO操作)对系统load的影响较大。( 注:该推断暂无数据或代码支撑,若有误,欢迎指正)
3. 理解load average背后的含义
上面介绍了load average的概念及linux系统对该指标的计算过程,那么,这个指标值到底怎么解读呢?这篇文章给出了详细且形象的说明,此处不再赘述。
【参考资料】
1. wikipedia: Load (computing)
2. linux源码(内核版本2.6.9)
3. Understanding Linux CPU Load - when should you be worried?
================== EOF ===================
linux主机load average的概念计算过程注意事项相关推荐
- Linux系统load average异常值处理的trick
周末再分享一个内核bug紧急热处理case. 假如你发现某个Linux系统的load输出如下: #uptime ... 0 users, load average: 32534565100.09, 3 ...
- 容器CPU使用率过高,导致宿主机load average飙升
早上醒来已经收到多条服务器告警信息,具体是这样的,如下图:Processor load (15 min average per core) ;服务器CPU load 过高,接下来是处理过程,记录一下. ...
- Linux操作系统load average过高,kworker占用较多cpu
Linux操作系统load average过高,kworker占用较多cpu 今天巡检发现,mc1的K8S服务器集群有些异常,负载不太均衡.其中10.2.75.32-34,49的load averag ...
- linux系统oracle启动过程,Linux主机下配置Oracle 10G自动启动过程记
四:创建服务 $su - root # cd /etc/rc.d/init.d/ # gedit oradbstart 复制如下脚本1或者脚本2内容到oradbstart文件: 注意点 (1).#开始 ...
- 深入理解 Linux Load Average
一直不解,为什么io占用较高时,系统负载也会变高,偶遇此文,终解吾惑. #1 load average介绍 ##1.1 load average 指标介绍 uptime和top等命令都可以看到load ...
- 详解多分类模型的Macro-F1/Precision/Recall计算过程
引入 关于准确率(accuracy).精度(precision).查全率(recall).F1的计算过程,之前写过一篇文章[1]. 根据文章[1]中的公式,我们可以知道,精度(precision).查 ...
- LINUX下CPU Load Average的一点研究
背景: 公司的某个系统工作在基于Linux的Cent OS下,一个host下同时连接了许多client, 最近某台Host总是显示CPU Load Average过高,我们单纯的以为是CPU的占用过高 ...
- php 系统平均负载,Linux_解析Linux系统的平均负载概念,一、什么是系统平均负载(Load a - phpStudy...
解析Linux系统的平均负载概念 一.什么是系统平均负载(Load average)?在Linux系统中,uptime.w.top等命令都会有系统平均负载load average的输出,那么什么是系统 ...
- linux中负载值为多少正常_Linux load average负载量分析与解决思路
一.load average top命令中load average显示的是最近1分钟.5分钟和15分钟的系统平均负载.系统平均负载表示 系统平均负载被定义为在特定时间间隔内运行队列中(在CPU上运行或 ...
最新文章
- 多线程-Thread、Runnable、Callbale、Future
- 巨坑!同事离职前一天,偷偷将一个470欧的色环电阻串进我的电源线中......
- 关于Java里如何跳出一个多重循环
- typecho怎么用html编写文章,为Typecho文章增加HTML标签支持
- 从零开始学习MXnet(四)计算图和粗细粒度以及自动求导
- JAVA压缩、解压,使用Apache Common Compress包下载链接
- matlab 梁代码,方舟生存进化梁龙鞍怎么做 梁龙鞍代码材料一览
- 国产6678开发记录
- 微信小程序开发常用方法
- html中左三角怎么写,css3三角形怎么写?
- 创业公司一年工作总结(转)(公司失败原因)
- 电脑笑脸蓝屏问题 也许你可以尝试一下这个
- 深大uooc学术道德与学术规范教育第七章
- Android源码中的目录结构详解
- 1081:分苹果(C C++)
- 在matlab中理解采样定理
- 武大计算机科学与技术弘毅学堂,武汉大学研究生精品课-百余新学子体验“弘毅学堂”...
- 架构设计文档提纲简描
- 轻松上手UAI-Train,拍拍贷人脸识别算法优化效率提升85.7%
- 6-Python数字和列表
热门文章
- token和session的区别
- mongodb如何快速进行版本升级
- 卷积输出的记录,为什么是([3, 0, 1, 2])
- linux下mysql开启远程访问权限及防火墙开放3306端口(mysql开放host访问权限)
- 每一个程序员都应该知道的高并发处理技巧、创业公司如何解决高并发问题、互联网高并发问题解决思路、caoz大神多年经验总结分享...
- Spring的IOC原理
- 29. Divide Two Integers
- Delphi RTC
- nullnullanimate用法
- BZOJ 1562 变换序列