PromQL 计算 CPU 使用率
Table of Contents
本文主要介绍如何使用 PromQL 计算 CPU 的使用(利用)率。
CPU 模式
在介绍之前,先了解下 CPU 的模式有哪些。在 Linux 机器上,使用 top
命令:
~# top
top - 12:13:21 up 93 days, 14:10, 1 user, load average: 0.00, 0.02, 0.00
Tasks: 132 total, 1 running, 131 sleeping, 0 stopped, 0 zombie
%Cpu(s): 1.0 us, 0.3 sy, 0.0 ni, 98.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
可以看到 CPU 一共有八种模式(状态),后面跟的数值是该模式的使用率,模式分别是:
- us: user 模式
- sy: system 模式
- ni: nice 模式
- id: idle 模式
- wa: iowait 模式
- hi: hardware interrupt 模式
- si: software interrupt 模式
- st: steal 模式
其中,user、system 和 idle 是 CPU 主要的模式。
注:准确说 CPU 一共是十种状态,还有两种:guest、guest_nice,它们的数值包含在 user 和 nice 状态中
CPU 时间
在 Prometheus 中,node_exporter 会抓取 node_cpu_seconds_total 指标,该指标会列出每种 CPU 模式占用的总共时长,单位是秒,如:
由于机器较多,并且每个机器的上有多个 CPU,所以先看一台机器上一个 CPU 的数据,使用 CPU 和 instance 标签过滤下:
可以看到,正好有八行记录,label 中的 mode 分别对应八种 CPU 模式,value 是自机器开机以来每种模式占用的总时长。根据上图第一个序列得知,IP 为 172.22.21.143 的机器的第 0 个 CPU idle 状态时长为:9286146.67s。
计算 CPU 使用率
到这里我们能够通过 PromQL 拿到一个 CPU 的每种模式的使用时长,而我们想要的是 CPU 使用率。
那么如何定义 CPU 的使用率?CPU 使用率 = 1 - CPU 空闲率,即:
CPU 使用率 = (1 - 所有空闲状态 CPU 时间总和 / 所有状态 CPU 时间总和) * 100%
为了简单,先计算一个机器上一个 CPU 在 2 分钟内处于空闲状态的时长,即:
increase(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100",mode="idle"}[2m])
这里用到了 promQL 的 increase 函数,该函数是计算一个时间范围内,Counter 指标类型的增量值。这里使用 increase 函数,计算出该 CPU 在 2 分钟内,空闲状态的时长,即 81.80s。
那么根据公式可得该 CPU 使用率:
1 - increase(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100",mode="idle"}[2m]) / 120
使用率为:32.93%。
或者使用:
1 - sum(increase(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100",mode="idle"}[2m])) / sum(increase(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100"}[2m]))
能达到同样的目的。该查询的分母:
sum(increase(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100"}[2m]))
其实就是 120 秒。
其实不用这么麻烦,promQL 提供了 rate
和 irate
函数,用来计算变化率:
1 - rate(node_cpu_seconds_total{cpu="0",instance="172.22.21.143:9100",mode="idle"}[2m])
分别查看一个机器上每个 CPU 使用率,即:
1 - sum by (cpu) (increase(node_cpu_seconds_total{mode="idle",instance="172.22.21.143:9100"}[2m])) / sum by (cpu) (increase(node_cpu_seconds_total{instance="172.22.21.143:9100"}[2m]))
查看一个机器上所有 CPU 的使用率,即:
1 - sum (increase(node_cpu_seconds_total{mode="idle",instance="172.22.21.143:9100"}[2m])) / sum (increase(node_cpu_seconds_total{instance="172.22.21.143:9100"}[2m]))
查看所有机器的 CPU 的使用率,即:
1 - sum by (instance)(increase(node_cpu_seconds_total{mode="idle"}[2m])) / sum by (instance)(increase(node_cpu_seconds_total[2m]))
也可以使用:
1 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[2m])))
查看所有机器的 CPU 使用率: