先放结论,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模式使用的总时间。


f702
1 声望1 粉丝