前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[linux][kernel]load average详细分析

[linux][kernel]load average详细分析

作者头像
皮振伟
发布2018-04-09 11:10:29
2.6K0
发布2018-04-09 11:10:29
举报
文章被收录于专栏:皮振伟的专栏皮振伟的专栏

前言: 朋友遇到了load average偏高的问题,关于load average的解释,网上也是五花八门,有的说法甚至都有些不负责任。在这里详细分析一下load average。 分析: 1,load average

如图,top命令的右上的load average: 0.21, 0.10, 0.04就是题目中要讨论的load average。

如图,uptime命令的右侧也是load average。 load average是从哪里来?是怎么计算出来的? 作者大概翻了以procps(代码下载路径http://procps.sourceforge.net/)这包代码: 在procps-3.2.8/proc/sysinfo.c中,

其中,#define LOADAVG_FILE "/proc/loadavg"。 可见,命令中的load average就是/proc/loadavg的前三项数据。 2,loadavg

查看loadavg,共六个参数。下面来分析这几个参数的意义。 代码linux-4.0.4/fs/proc/loadavg.c文件中:

前三个参数(例子中的0.12 0.08 0.11)avnrun从get_avenrun函数中获取到。 第四个参数(例子中的1),是所有处于running状态的task的总数。注意,这里的task,其实对应的是用户态的线程,不是进程!!!代码实现在linux-4.0.4/kernel/sched/core.c中。 第五个参数(例子中的620)是所有的task的总数。同样,这里也指的是用户态线程。 第六个参数(例子中的3487)是当前namespace中的最后一个pid。像docker和lxc,都是基于namespace的隔离技术的。 再来进一步分析get_avenrun,代码实现在linux-4.0.4/kernel/sched/proc.c中,大意就是计算1分钟,5分钟,15分钟内的CPU的running队列上平均task数量(记得是线程):

从代码注释中,可以看到非常非常非常关键的一点: nr_active += cpu_of(cpu)->nr_running + cpu_of(cpu)->nr_uninterruptible; 计算出来的结果中,不但包括处于running状态的task(对应了用户态的R状态),还包括了 uninterruptible状态的task(对应了用户态的D状态)。 3,analysis 结合上述的分析,进一步来说,假设操作系统状态非常好,内存和IO都是及时响应的,那么D状态的task几乎没有,或者说处于D状态的时间非常非常少,那么load average的值略小于CPU核心数应该是最好的情况。原因一,平均下来,每个任务都有充分的CPU时间来执行;原因二,是保证CPU的利用率相对都比较充分。以作者的经验来看(或者说在某鹅开发后台的时候,有个不算是规则的规则):如果集群的平均CPU利用率超过80%的时候,就需要扩容了。 当然,上述是理想情况,可实际并非如此, uninterruptible还是会触发。作者大概想到了几种情况,例如: a,缺页中断。Linux为了提高内存利用率,会比较投机,比如说著名的LRU回收。举例子来说,如果进程的page已经被回收并交换的swap分区上,那么进程访问到页面的时候开始,就要陷入uninterruptible状态,一直到页面被加载到内存中;如果运气比较差,内存比较紧张,还需要先回收一些page才行。 b,io等待。磁盘速度是计算机的最大瓶颈。多个进程都要访问磁盘的话,势必有进程要处于uninterruptible状态排队,直到数据被读到内存。运气差一些的话,如果操作系统的内存偏少,还需要先回收一些内存才能把数据读进内存来。 c,网络。平常写的socket,大家放心,不会让进程进入到uninterruptible状态的。但是,如果是nfs或者cifs呢,再或者iscsi映射的块设备呢?如果发生了网络波动,读写就会陷入uninterruptible了。(nfs和cifs作者实验过,是会陷入uninterruptible状态的。iscsi没有实验过,这个算是作者偷懒了)。作者实验了一下,在使用nfs的情况下,server端使用iptables DROP掉2409的包,client端访问nfs目录的时候,果然发生了load average增高的情况。当然,这个是符合预期的。 d,CPU绑定。如果是了类似sched_setaffinity这样的函数,绑定了CPU,那么也可能会出问题。作者写了一段测试代码:

好吧,不讨论代码的严谨性,大概意思就是创建100个线程,只作简单的cpu消耗。使用taskset来绑定cpu。在shell中执行:taskset 1 ./cpuburn 效果图如下:

比较奇怪的现象出现了:总体的CPU使用了13.2%(作者的机器是8CPU,那么一个CPU跑满几乎就是12.5%,再加上一点点其他的CPU使用,所以这个数值是合理的),但是load average却高达101。当然,这个现象也是预期的。这里也再次证明了作者前面重复的:load average是统计线程的,不是进程!!! e,操作系统free memory少。原因上面已经解释过了,这里强调一下,是为了说明,free memory越少,越容易让load average增高!!!swap的内存越多,load average也越容易增高。这里作者没有实验数据,不过作者猜测,当内存利用率达到某个阈值的时候,每增大一点点内存使用,可能会让load average的大幅度增大。 回头看问题,所谓的“load average偏高”,那么多少算高,什么样的数值是合理的? 作者这里也没有具体的实验数据,不过作者觉得,还是要根据场景来分析。如果CPU密集型的,那么load average最好不要超过CPU核心数太多。如果是IO密集型的,这里稍微高一些,达到了CPU核心数的两倍(作者估计的,没有实验数据来支撑,囧),也没有太大问题;如果再高一些的话,估计就要查一查了,估计磁盘性能真的是瓶颈了,或者nfs的网络不佳,再或者nfs server的磁盘是瓶颈了。 解决这个问题的关键,还是要分析清楚触发load average高的原因。合理解决。 后记: 关于触发load average偏高的case,希望看到的朋友可以帮忙补充;如果有具体的实验数据,也欢迎补充。因为关注的人数不够,点击量比较少的原因,目前公众号还不能开通评论功能。可以直接回复消息,作者看到后也会回复的。 最后,推荐一下procps的源代码,里面实现了vmstat,top,ps,slabtop,free等常用命令。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-02-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AlwaysGeek 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档