先放结论,Prometheus中采集的原始指标无法直接表示CPU使用率,需要通过promQL语言二次计算,计算公式如下:
sum by(instance)(rate(node_cpu_seconds_total{mode!="idle"}[15s])) / sum by(instance)(rate(node_cpu_seconds_total[15s]))
该公式的计算原理与top命令中计算cpu使用率的方法一样:非idle模式占用的时间 / 该cpu核心的全部时间。
不同的是,top命令是直接使用单项差值除以总差值,分子分母单位都为ticks
。该公式中,是速率除以速率,即每秒单项占用的秒除以每秒全部占用的秒,分子分母单位都为秒/秒
。
但是想要完全理解公式,还有很多疑点:
- 同样的数据来源,单位是什么时候从
ticks
转化成了秒
? - 公式中
[15s]
是什么意思? rate()
,sum by()
又是什么意思?
1. 单位统一
数据从linux系统中读取时单位是ticks,由于采集器是以秒为最小精度进行周期性采集,在采集时会给数据打上当下以秒为单位的时间标签,自从数据单位转为秒。
所有数据的单位均为秒,因此除以时间步长时,也直接使用秒。单位统一过程如下所示:
/proc/stat(单位:ticks)
↓
node_exporter(转换 ticks → 秒)
↓
Prometheus 抓取指标(单位:秒)
↓
rate(metric[15s]) → 输出“秒/秒”
2.时间窗口(range vector)与采样间隔(scrape interval)
rate()
是promQL中的函数,该函数计算时,不是单纯用时间窗口两头的值/时间窗口长度,而是用采样间隔采集到的相邻数据进行线性回归(最小二乘法拟合)。因此rate()
函数得到的是该时间窗口内的平均速率。
3.cpu多核心速率聚合
sum by()
同样是promQL中的函数,instance
是标签,通常按主机ip区分,不sum by()
就会得到该主机上各个cpu核各自的使用率,同一个instance
相加,才能得到所有核的cpu使用率,即整个主机的cpu使用率。
sum by()
的相加是对各个核的速率的相加,不是百分比!算出所有核在总时间内,非idle模式使用的总时间。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。