一、重点知识回顾
储备知识1:linux进程状态
储备知识2:关于cpu的使用情况有两个参考指标
二、引入今日问题
我们可以使用cpu cgroup对容器的cpu资源进行限制,但是cpu cgroup并非是万能的,它无法限制Load Average,没有这个限制,会影响我们对资源的合理调度,进而导致系统变得很慢
例如:
有时你会遇到所有容器进程、以及宿主机的cpu使用率都很低,但是容器里的应用运行速度非常慢,并且查看宿主机的Load Average的平均负载会发现非常高。
这到底是因为什么导致的呢?
其实这与linux系统的Load Average的统计方式有关
在linux操作系统中,Load Average把不可中断睡眠状态的进程也当成是活跃的进程,并计算到了Load Average里
所以如果系统中有大量进程处于D状态,会导致Load Average增高,而D状态作为一种睡眠状态是不会消耗cpu的,所以cpu利用率会很低
问题展示
先来查看一下初始的load average,cpu的剩余很充足,load average也不高
然后我来模拟一下,cpu idle剩余率很多、cpu很充足,但是load average非常高
让子弹飞一会之后,再次查看你会发现cpu剩余率量大很充足,但是平均负载却很高
接下来问题就来
1、我们查看一个cpu的使用情况,到底是以cpu usage为准,还是以load average为准呢?
2、D状态的进程为何会导致load average升高呢?
三、Load Average的统计方式
top命令可以看到load average,分别对应1分钟、5分钟、15分钟的cpu平均负载
为何linux操作系统会把不可中断睡眠也计算到Load Average里
——————–》答案
linux起源于unix,早在unix系统里,就有load average的概念了,但是在unix系统里没有把不可中断睡眠D状态的进程数计算到Load Average里,而在linux系统里却把不可中断睡眠D状态的进程数计算到Load Average里了
-
1、在大多数unix发行版里:
load average = 正在运行的进程数 + 处于就绪的进程数(即已经存在于操作系统的进程可运行队列里,只要申请到cpu资源即可投入运行的进程) -
2、而在linux系统里:
load average=正在运行的进程数 + 处于就绪的进程数 + 休眠队列中处于不可中断睡眠D状态的进程数
linux系统为何要这么做呢???
要解答这个疑问,你必须要搞明白Load Average这个指标到底要反应什么?
打个比方,
为了思考方便,先假设你的机器就一个cpu
- 一个进程都是向前行进的一辆车
- 既然一个进程可以被比喻为一辆往前行进的车,那负责运行(或者说承载)进程的cpu就相当于一条单行车道(同一时间只允许通行一辆车)
- 而load average反应的就是整个系统的交通情况,具体是指所有条路的单位时间通过的车辆数(即活跃的进程数)
- D状态的进程就好比是车辆在等待红灯,而且是不可中断的等,毫无疑问这辆车应该被认为是处于活跃状态,处于D状态,虽然不消耗cpu、不会统计到cpu占用率里,但是它一定是活跃的进程
- S状态的进程就好比是车辆停在你加车库里呢
你仔细思考一下,如果我们要反应路况情况,肯定是需要把等待红灯的情况即D状态也考虑进去,这种统计更为科学,一条路的路况肯定是需要考虑红绿灯情况的,想想就明白了,哪怕有一条路很空(cpu利用率很低),但是红绿特别多,汽车也需要排队,不可能开快。如果这辆车是出租车你作为客户坐在车里的直观感受就是车开的很慢
所以说Load Average反应的是整个系统的任务量/负载量情况
而cpu利用率反应的则是每个cpu的利用情况
如果我们把整个系统比喻为一家公司,load average反应的就是这家公司的办事效率,而cpu反应的就是每个员工的偷懒程度,正常情况是,每个员工的偷懒很少、利用率高,同时这家公司的办事效率也高
不正常情况是,在开月底总结大会的时候,老板发现公司正在办的事很多,但是每个员工都很闲,此时可能的原因就是大量的事情都处于不可中断的等待过程中,这是需要优化的,不然哪怕这家公司每员工的能力都是超人pro,那这家公司的整体运作效率也不高
综上,如果 IO 设备出现瓶颈,势必会造成大量的进程处于等待 IO 的状态,这种情况下,虽然不关 CPU 什么事,整个系统的处理能力其实已经出现的很大的瓶颈,
所以把 D 状态的进程算在平均负载里也还算合理。当系统 load average 比较高时,首先我们需要去甄别,到底是 CPU 的问题还是 IO 的问题。
有4颗cpu,满负载任务数就为4,超了就要分析原因了,看看是否是D状态带来的影响。
因为当D状态过多,就可能程序出一种效果:所有进程的cpu占用率非常低,但是cpu的1分钟5分钟15分钟负载非常高,这个会影响k8s的调度
示例:在系统没有大量的D状态进程时,linux系统的load average的增长与cpu利用率趋于一致
我们启动一个占用2颗cpu的的进程,会发现一分钟负责为2.08与我们的cpu usage吻合,此外我们有4颗cpu,你占用2颗,所以总使用率为50%
但如果我们启动了大量的D进程,load average便不会与cpu usage一致,而是会超过它