文章转自:原创: 杨建旭 https://mp.weixin.qq.com/s/gPkxJnZAI0B-vBgcR6CwyQ

有时我们说到nmon、topas、ps等几个命令中显示的CPU利用率不一致,那可以归结为CPU利用率的算法不一致,其实也就是分母不一致导致(除以不同数量的CPU)。

但很多同学在看nmon中的CPU利用率的时候都表示困惑,同是一份nmon报告,好几处出现CPU利用率的地方,为什么也不一致。由于从来就没有什么文档来介绍这些数据之间的关联,本节就来解释这些问题。

CPU_ALL和TOP页不一致

首先我们看CPU_ALL这个Sheet,CPU利用率大概是75%的样子。

有时候想知道是哪些进程占了CPU,我们就切换到TOP这个Sheet。

问题来了,占用CPU最高的进程是cicsas,平均利用率(WAvg)是17%。而其他进程最大也就2%的平均利用率,而且这样的进程只有5个。那么总CPU利用率75%是怎么凑出来?

Avg和WAvg的区别


说这个问题之前,我们先解释一下进程CPU利用率中Avg、WAvg的含义和区别。

Avg是这段时间内利用率的平均值。

WAvg,这个是重点,WAvg是除去0值之后的平均值。所以WAvg一定是大于等于Avg的。绝大多数情况下,我们看是WAvg而不是Avg。因为我们统计的是进程运行时候的占用情况,图1就是一个例子。中间有不运行的时间段,统计avg是没有意义的。 

CPU_ALL和TOP的统一


言归正传,总CPU利用率75%是怎么凑出来?我们还得从头说起。

TOP Sheet中按照command筛选,把那个CPU最高的进程(cicsas)选出来。我们看到15:30:52这个时间点有20个cicsas进程,可以用肉眼数出来,也可以看Threads这个列的数据。当然肉眼数的结果和Threads列显示的结果不一定一致。因为肉眼看到的是CPU利用率排到top的进程,没有进入top行列是不会显示出来的。 

本次nmon的监控是30秒一次,这20个进程是同一个时间点(15:30:52)监控出来的,而不是从15:30:52到15:31:12这30秒内陆陆续续监控出来的。也就是说,当前系统cicsas进程的并发数是20.

这20个cicsas进程每个进程都有24%左右的CPU利用率,它们加起来有240%,这是什么鬼?

明显超过了100%,那么说明每个进程的CPU利用率都是针对单个CPU的利用率,而不是针对系统所有CPU的利用率。也就是说CPU利用率的计算公式中,分母是1。假如系统中有个10个CPU,有1个进程P,P占用了一整颗CPU,利用率为100%,不考虑其他进程,我们看整机的CPU_ALL中的利用率就是10%。

其实在解释Avg的时候并没有解释清楚,我们继续解释。avg这个利用率指的是相同进程名的所有进程的平均值,另外还有一个时间维度,不同时间点的平均值再进行一次平均,就得到了Avg这个值。如果除去0值做平均,得到是WAvg这个值。

所以,在这个CPU的TOP的图上,有时候我们看到柱子高的进程占用CPU不一定最多,因为还需要把进程的数量考虑在内。

在图2中,WAvg是17.5%左右,由于有20个进程,它们总的CPU占用是17.5%*20=350%。而这个值是相对于单颗CPU的利用率,我们只要除以CPU总数应该就可以和CPU_ALL中的75%对应上了。此时似乎疑团散去,但问题还在后面。

好了,我们来看看这个LPAR的CPU配置,来到BBBL Sheet

8颗虚拟处理器,2个EC。

刚才计算的350%,除以8=43.75%,除以2=175%,和我们的目标75%明显不着边。这。。难道我们分析错了吗?

为了解释清楚这件事,我们需要从CPU_ALL的算法开始说。

由于大家大脑中的CPU利用率最多是100%,不能再多了。而虚拟化之后,有超过标称计算能力(EC)一说,比如分配了2个core的能力(EC=2),而运行当中,由于2个core的能力不够,LPAR抢占了3个core的能力,这时候CPU利用率按理说就是150%了。事实上,topas这个命令有个Entc这个指标,大致就是这个意思。如果Entc超过100%,就说明当前占用的物理CPU的数量已经超过了预设的EC。

但NMON的设计者担心具有传统思维的遗老遗少接受不了150%这个现实,就把CPU利用率强行控制在100%以内。方法嘛就是增大分母,分母是多少呢?

从LPAR Sheet看出,运行时获得的物理CPU的数量(蓝色线)是动态的,而且大部分时候是超过2C的,右侧有压力的时间段,平均值大概是5。

我们的350%除以5=70%。这就和75%基本对上了。75%和70%之间的5%是cicsas这个超级CPU饭桶之外的那些小进程的消耗。

CPU_ALL和LPAR页的统一


需要说明的是,CPU_ALL算法里面分母是动态的,因为运行时获得物理CPU数量是动态的。

但并不是所有时候分母都是动态的。

当Physical CPU>EC时,CPU利用率=(用户态CPU+系统态CPU)/运行时物理CPU,也就是物理CPU利用率。

当Physical CPU<=EC时,CPU利用率=(用户态CPU+系统态CPU)/EC值。

通过这样的算法,当Physical CPU很小,约等于0的时候,可以看到CPU利用率也基本=0,而不会出现本来没用CPU但CPU利用率很高的误导图形

但不管怎么说,这个CPU_ALL还是比较误导人。你分母是变的,我统计CPU利用率到底是多少颗CPU的利用率呢?

这里我们可以引入一个VP利用率的指标。这个指标的好处是分母是固定的,分母就是VP的数量

VP利用率=(用户态CPU+系统态CPU)/VP值

图中的例子,看16:11:13这个时间点

EC利用率=135.54%+53.01%=188.55%,EC=2,就是说按照2颗CPU来说,当前LPAR占用了2*188.55%=3.771颗CPU

VP利用率=33.88%+13.25%=47.13,VP=8,按照8颗CPU来说,当前LPAR占用了8*47.13%=3.7704颗CPU

而CPU­_ALL中的CPU利用率=3.77/5.076=74.3%

我们跳转到CPU_ALL Sheet看看16:11:13,CPU%果然是74.3%。

所以,对于这种physical CPU超过EC,飘忽不定的分母,是不能用CPU_ALL中的数值的,而应该用LPAR中的VP利用率=(用户态CPU+系统态CPU)/VP值。出具统计结果的时候,可以说“在8颗CPU的时候,CPU利用率是xxx%”。

阅读原文

posted on 2019-12-27 17:47  淡然~~浅笑  阅读(1573)  评论(0编辑  收藏  举报