本章概述
- PromQL数据基础
- PromQL-指标数据
- PromQL匹配器
- PromQL-时间范围
- PromQL-运算符
- PromQL-聚合运算
前言
官网链接:https://prometheus.io/docs/prometheus/latest/querying/basics/
Prometheus提供一个函数式的表达式语言PromQL (Prometheus Query Language),可以使用户实时地查找和聚合时间序列数据,表达式计算结果可以在图表中展示,也可以在Prometheus表达式浏览器中以表格形式展示,或者作为数据源, 以HTTP API的方式提供给外部系统使用。
3.1 PromQL数据基础
3.1.1 PromQL数据分类
瞬时向量、瞬时数据(instant vector):
是一组时间序列,每个时间序列包含单个数据样本,比如node_memory_MemFree_bytes查询当前剩余内存就是一个瞬时向量,该表达式的返回值中只会包含该时间序列中的最新的一个样本值,而相应的这样的表达式称之为瞬时向量表达式,例如:prometheus_http_requests_total
在prometheus控制台查询node_memory_MemFree_bytes
在prometheus控制台查询prometheus_http_requests_total
范围向量、范围数据(range vector):
是指在任何一个时间范围内,抓取的所有度量指标数据。比如最近一天的网卡流量趋势图,例如:prometheus_http_requests_total[5m]
注意:prometheus每隔15秒抓取一次数据,一分钟会抓取4此,如果查询5分钟内的数据,那么会返回5*(60/15)=20个数据的值
标量、纯量数据(scalar):
是一个浮点数类型的数据值,使用node_load1获取到一个瞬时向量,但是可以使用内置函数scalar()将瞬时向量转换为标量,例如:scalar(sum(node_load1))
字符串(string):
简单的字符串类型的数据,目前未使用,(a simple string value; currentlyunused)。
3.1.2 PromQL数据类型
包括四类:
counter(只增不减 计数)
Gauge(常规数值 可变化大小)
histogram(柱状图 小于上边界的 总数与次数)
summary(分位数 小于自定义值的百分比 总数与次数)
1、Counter:
计数器,Counter类型代表一个累积的指标数据,在没有被重置的前提下只增不减,比如磁盘I/O总数、nginx的请求总数、网卡流经的报文总数等。
特点:
(1)Counter 用于累计值、统计值,例如记录请求次数、任务完成数、错误发生次数
(2)一直增加,不会减少。
(3)重启进程后,会被重置。
2、Gauge:
仪表盘,Gauge类型代表一个可以任意变化的指标数据,值可以随时增高或减少,如带宽速录、CPU负载、内存利⽤率、nginx 活动连接数等。
特点:
(1)Gauge是常规数值,例如温度变化、内存使用变化,用于记录数据的实时变化
(2)可变大,可变小。
(3)重启进程后,会被重置
3、Histogram:
累积直方图,也可以叫柱状图。Histogram会在一段时间范围内对数据进⾏采样(通常是请求持续时间或响应大小等)
特点:
(1)在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入可配置的存储桶(bucket)中,后续可通过指定区间筛选样本,也可以统计样本总数,最后一般将数据展示为直方图。
(2)对每个采样点值累计和(sum)
(3)对采样点的次数累计和(count)
假如每分钟产生一个当前的活跃连接数,那么一天就会产生1440个数据,查看数据的每间隔的绘图跨度为2小时,那么2点的柱状图(bucket)会包含0点到2点即两个小时的数据,而4点的柱状图(bucket)则会包含0点到4点的数据。而6点的柱状图(bucket)则会包含0点到6点的数据。
为什需要用histogram柱状图?
在大多数情况下人们都倾向于使用某些量化指标的平均值,例如 CPU 的平均使用率、页面的平均响应时间。这种方式的问题很明显,以系统 API 调用的平均响应时间为例:如果大多数 API 请求都维持在 100ms 的响应时间范围内,而个别请求的响应时间需要 5s,那么就会导致某些 WEB 页面的响应时间落到中位数的情况,而这种现象被称为长尾问题。
为了区分是平均的慢还是长尾的慢,最简单的方式就是按照请求延迟的范围进行分组。例如,统计延迟在 0~10ms 之间的请求数有多少,而 10~20ms 之间的请求数又有多少。通过这种方式可以快速分析系统慢的原因。Histogram 和 Summary 都是为了能够解决这样问题的存在,通过 Histogram 和 Summary 类型的监控指标,我们可以快速了解监控样本的分布情况。
4、Summary:
摘要,也是一组数据,统计的不是区间的个数而是统计分位数,从0到1,表示是0%~100%,如下统计的是 0、0.25、0.5、0.75、1的数据量分别是多少
3.2 PromQL-指标数据
node_memory_MemTotal_bytes #查询node节点总内存大小
node_memory_MemFree_bytes #查询node节点剩余可用内存
node_memory_MemTotal_bytes{instance="172.31.7.192:9100"} #基于标签查询指定节点的总内存
node_memory_MemFree_bytes{instance="172.31.7.192:9100"} #基于标签查询指定节点的可用内存
node_disk_io_time_seconds_total{device="sda"} #查询指定磁盘的每秒磁盘io
node_filesystem_free_bytes{device="/dev/sda1",fstype="xfs",mountpoint="/boot"} #查看指定磁盘的磁盘剩余空间
3.3 PromQL匹配器
匹配器包括:
= :选择与提供的字符串完全相同的标签,精确匹配。
!= :选择与提供的字符串不相同的标签,去反。
=~ :选择正则表达式与提供的字符串(或子字符串)相匹配的标签。
!~ :选择正则表达式与提供的字符串(或子字符串)不匹配的标签。
查询格式:
<metric name>{<label name>=<label value>, ...}
示例:
node_load1{instance="172.31.7.192:9100", job="prometheus"} #精确匹配
node_load1{instance!="172.31.7.192:9100", job="prometheus"} #取反
node_load1{instance=~"172.31.7.*:9100$"} #包含正则且匹配(查询以172.31.7开头的主机)
node_load1{instance!~"172.31.7.191:9100"} #包含正则且取反(查询不包括以172.31.7.191的主机)
3.4 PromQL-时间范围
时间包括:
s - 秒
m - 分钟
h – 小时
d - 天
w - 周
y - 年
示例:
瞬时向量表达式,选择当前最新的数据
node_memory_MemTotal_bytes{}
区间向量表达式,选择以当前时间为基准,查询所有节点node_memory_MemTotal_bytes指标1分钟内的数据
node_memory_MemTotal_bytes{}[1m]
区间向量表达式,选择以当前时间为基准,查询指定节点node_memory_MemTotal_bytes指标5分钟内的数据
node_memory_MemTotal_bytes{instance="172.31.7.111:9100"}[5m]
3.5 PromQL-运算符
运算符包括:
+ 加法
- 减法
* 乘法
/ 除法
% 模
^ 幂等
示例:
node_memory_MemFree_bytes/1024/1024 #将内存单位从字节转换为兆
node_disk_read_bytes_total{device="sda"}+node_disk_written_bytes_total{device="sda"} #计算磁盘读写数据量
(node_memory_MemTotal_bytes-node_memory_MemFree_bytes)/node_memory_MemTotal_bytes #计算内存当前使用率
3.6 PromQL-聚合运算
3.6.1 max、min、avg
参数说明:
max() #最大值
min() #最小值
avg() #平均值
示例:
计算每个节点的最大的流量值:
max(node_network_receive_bytes_total) by (instance)
计算每个节点最近五分钟每个device的最大流量
max(rate(node_network_receive_bytes_total[5m])) by (device)
3.6.2 sum、count
sum() #求数据值相加的和(总数)
sum(prometheus_http_requests_total){} #下图中2757是指 最近总共请求数为2757次,用于计算返回值的总数(如http请求次数)
count() #统计返回值的条数
count(node_os_version) #下图中3表示一共3条返回的数据,可以用于统计节点数、pod数量等
count_values() #对value的个数(行数)进行计数
count_values("node_version",node_os_version) #统计不同的系统版本节点有多少
3.6.3 abs、absent
abs() #返回指标数据的值
abs(sum(prometheus_http_requests_total{handler="/metrics"})) #返回请求prometheus监控url为/metrics的总次数的值
absent()
如果监指标有数据就返回空,如果监控项没有数据就返回1,可用于对监控项设置告警通知
absent(sum(prometheus_http_requests_total{handler="/metrics"})) #返回为空,说明有数据
absent(sum(prometheus_http_requests_total{handler="/metrics"})) #假如请求一个不存在的url /metricsxx,返回为1,说明没数据
3.6.4 stddev、stdvar
stddev() #标准差
比如5+5=10,1+9=10,那么1+9这一组的数据差异就大,在系统上表示数据波动较大,不稳定
stddev(prometheus_http_requests_total) #得出的值越大,说明差异越大,表示数据波动大,不稳定
stdvar() #求方差
stdvar(prometheus_http_requests_total) #进行平方运算得出的值
3.6.5 topk、bottomk
topk() #样本值排名最大的N个数据
topk(6, prometheus_http_requests_total) #取从大到小的前6个
bottomk() #样本值排名最小的N个数据
bottomk(6, prometheus_http_requests_total) #取从小到大的前6个
3.6.6 rate、irate
这两个参数广泛用于监控网卡速率
rate()
rate()函数是专门搭配counter数据类型使⽤函数,其功能是取counter数据类型在这个时间段中平均每秒的增量平均数,适合用于计算数据相对平稳的数据。
rate(prometheus_http_requests_total[5m]) #取出5分钟的数据,计算每秒的平均数
rate(node_network_receive_bytes_total[5m]) #取出5分钟的数据,计算每秒的平均数
irate()
irate()函数是专门搭配counter数据类型使⽤函数,irate获取的是指定时间范围内最近的两个数据来计算数据的差异,适合计算数据变化比较大的数据,显示的数据相对比较准确。
irate(prometheus_http_requests_total[5m]) #5分钟内最近的两个请求总量的差异
irate(node_network_receive_bytes_total[5m]) #5分钟内最近的两个接收字节总量的速率
3.6.7 by、without
by,在计算结果中,只保留by指定的标签的值,并移除其它所有的
sum(rate(node_network_receive_packets_total{instance=~".*"}[10m])) by(instance)
sum(rate(node_memory_MemFree_bytes[5m])) by (increase)
without,从计算结果中移除指定的instance,job标签,保留其它标签
sum(prometheus_http_requests_total) without (instance,job)
文章评论