Linux|浅谈 Linux 高负载的系统化分析

Linux|浅谈 Linux 高负载的系统化分析

文章图片

Linux|浅谈 Linux 高负载的系统化分析

文章图片

Linux|浅谈 Linux 高负载的系统化分析

文章图片


讲解 Linux Load 高如何排查的话题属于老生常谈了 , 但多数文章只是聚焦了几个点 , 缺少整体排查思路的介绍 。 所谓 “授人以鱼不如授人以渔” 。 本文试图建立一个方法和套路 , 来帮助读者对 Load 高问题排查有一个更全面的认识 。
从消除误解开始 没有基线的 Load , 是不靠谱的 Load
从接触 Unix/Linux 系统管理的第一天起 , 很多人就开始接触 System Load Average 这个监控指标了 , 然而 , 并非所有人都知道这个指标的真正含义 。 一般说来 , 经常能听到以下误解:
Load 高是 CPU 负载高……传统 Unix 于 Linux 设计不同 。 Unix 系统 , Load 高就是可运行进程多引发的 , 但对 Linux 来说不是 。 对 Linux 来说 Load 高可能有两种情况: 系统中处于 R 状态的进程数增加引发的 系统中处于 D 状态的进程数增加引发的 Loadavg 数值大于某个值就一定有问题……Loadavg 的数值是相对值 , 受到 CPU 和 IO 设备多少的影响 , 甚至会受到某些软件定义的虚拟资源的影响 。 Load 高的判断需要基于某个历史基线 (Baseline) , 不能无原则的跨系统去比较 Load 。Load 高系统一定很忙…..Load 高系统可以很忙 , 例如 CPU 负载高 , CPU 很忙 。 但 Load 高 , 系统不都很忙 , 如 IO 负载高 , 磁盘可以很忙 , 但 CPU 可以比较空闲 , 如 iowait 高 。 这里要注意 , iowait 本质上是一种特殊的 CPU 空闲状态 。 另一种 Load 高 , 可能 CPU 和磁盘外设都很空闲 , 可能支持锁竞争引起的 , 这时候 CPU 时间里 , iowait 不高 , 但 idle 高 。Brendan Gregg 在最近的博客 [Linux Load Averages: Solving the Mystery
(http://www.brendangregg.com/blog/2017-08-08/linux-load-averages.html) 中 , 讨论了 Unix 和 Linux Load Average 的差异 , 并且回朔到 24 年前 Linux 社区的讨论 , 并找到了当时为什么 Linux 要修改 Unix Load Average 的定义 。 文章认为 , 正是由于 Linux 引入的 D 状态线程的计算方式 , 从而导致 Load 高的原因变得含混起来 。 因为系统中引发 D 状态切换的原因实在是太多了 , 绝非 IO 负载 , 锁竞争这么简单!正是由于这种含混 , Load 的数值更加难以跨系统 , 跨应用类型去比较 。 所有 Load 高低的依据 , 全都应该基于历史的基线 。 本微信公众号也曾写过一篇相关文章 , 可以参见Linux Load Average那些事儿 。

如何排查 Load 高的问题 如前所述 , 由于在 Linux 操作系统里 , Load 是一个定义及其含混的指标 , 排查 loadavg 高就是一个很复杂的过程 。 其基本思路就是 , 根据引起 Load 变化的根源是 R 状态任务增多 , 还是 D 状态任务增多 , 来进入到不同的流程 。
这里给出了 Load 增高的排查的一般套路 , 仅供参考:

在 Linux 系统里 , 读取 /proc/stat 文件 , 即可获取系统中 R 状态的进程数;但 D 状态的任务数恐怕最直接的方式还是使用 ps 命令比较方便 。 而 /proc/stat 文件里 procs_blocked 则给出的是处于等待磁盘 IO 的进程数:

通过简单区分 R 状态任务增多 , 还是 D 状态任务增多 , 我们就可以进入到不同的排查流程里 。 下面 , 我们就这个大图的排查思路 , 做一个简单的梳理 。
R 状态任务增多
即通常所说的 CPU 负载高 。 此类问题的排查定位主要思路是系统 , 容器 , 进程的运行时间分析上 , 找到在 CPU 上的热点路径 , 或者分析 CPU 的运行时间主要是在哪段代码上 。