第三章 PromQL 学习与实践

一、概述

Prometheus 通过指标名称(metrics name)以及对应的一组标签(labelset)唯一定义一条时间序列。指标名称反映了监控样本的基本标识,而 label 则在这个基本特征上为采集到的数据提供了多种特征维度。用户可以基于这些特征维度过滤,聚合,统计从而产生新的计算后的一条时间序列。

PromQL 是 Prometheus 内置的数据查询语言,其提供对时间序列数据丰富的查询,聚合以及逻辑运算能力的支持。并且被广泛应用在Prometheus  的日常应用当中,包括对数据查询、可视化、告警处理当中。可以这么说,PromQL 是Prometheus 所有应用场景的基础,理解和掌握 PromQL 是 Prometheus 入门的第一课。

瞬时向量:包含该时间序列中最新的⼀个样本值
区间向量:⼀段时间范围内的数据

二、查询时间序列

Prometheus 通过 Exporter 采集到相应的监控指标样本数据后,我们就可以通过PromQL 对监控样本数据进行查询。

#1.当我们直接使用监控指标名称查询时,可以查询该指标下的所有时间序列。如:
prometheus_http_requests_total	
等同于:
prometheus_http_requests_total{}	
该表达式会返回指标名称为 prometheus_http_requests_total 的所有时间序列:

#2.PromQL 还支持用户根据时间序列的标签匹配模式来对时间序列进行过滤,目前主要支持两种匹配模式:完全匹配和正则匹配。
PromQL 支持使用 = 和 != 两种完全匹配模式: 
1)通过使用 label=value 可以选择那些标签满足表达式定义的时间序列;
2)反之使用 label!=value 则可以根据标签匹配排除时间序列;

例如,如果我们只需要查询所有 prometheus_http_requests_total 时间序列中满足标签 instance 为 localhost:9090 的时间 序列,则可以使用如下表达式:
prometheus_http_requests_total{instance="localhost:9090"}	
反之使用 instance!="localhost:9090" 则可以排除这些时间序列:
prometheus_http_requests_total{instance!="localhost:9090"}	

#3.PromQL 还可以支持使用正则表达式作为匹配条件,多个表达式之间使用 | 进行分离:
1)使用 label=~regx 表示选择那些标签符合正则表达式定义的时间序列;
2)反之使用 label!~regx 进行排除;

例如,如果想查询多个环节下的时间序列序列可以使用如下表达式:
prometheus_http_requests_total{environment=~"staging|testing|development",method!="GET"}

排除用法
prometheus_http_requests_total{environment!~"staging|testing|development",method!="GET"}

三、范围查询

直接通过类似于PromQL 表达式 httprequeststotal 查询时间序列时,返回值中只会包含该时间序列中的最新的一个样本值,这样的返回结果我们称之为瞬时向量。而相应的这样的表达式称之为 瞬时向量表达式。

而如果我们想过去一段时间范围内的样本数据时,我们则需要使用区间向量表达式。

区间向量表达式和瞬时向量表达式之间的差异在于在区间向量表达式中我们需要定义时间选择的范围,时间范围通过时间范围选择器 [] 进行定义。 例如,通过以下表达式可以选择最近 5 分钟内的所有样本数据:
prometheus_http_requests_total{}[5m]	

该表达式将会返回查询到的时间序列中最近 5 分钟的所有样本数据:
prometheus_http_requests_total{code="200",handler="alerts",instance="localhost:9090",job="prometheus",method="get"}=[
1@1518096812.326
1@1518096817.326
1@1518096822.326
1@1518096827.326
1@1518096832.326
1@1518096837.325
] 
 
通过区间向量表达式查询到的结果我们称为区间向量。 除了使用 m 表示分钟以外,
PromQL 的时间范围选择器支持其它时间单位:
1)s - 秒
2)m - 分 钟
3)h - 小 时
4)d - 天
5)w - 周
6)y - 年

四、时间位移操作

在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准:
prometheus_http_requests_total{} # 瞬时向量表达式,选择当前最新的数据
prometheus_http_requests_total{}[5m] # 区间向量表达式,选择以当前时间为基准,5分钟内的数据
 
而如果我们想查询,5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据呢? 这个时候我们就可以使用位移操作,位移操作的关键字为 offset。 可以使用 offset 时间位移操作:
prometheus_http_requests_total{} offset 5m
prometheus_http_requests_total{}[1d] offset 1d

五、使用聚合操作

一般来说,如果描述样本特征的标签(label)在并非唯一的情况下,通过 PromQL 查询数据,会返回多条满足这些特征维度的时间序列。而 PromQL 提供的聚合操作可以用来对这些时间序列进行处理,形成一条新的时间序列:

# 查询系统所有 http 请求的总量
sum(prometheus_http_requests_total)

# 按照 mode 计算主机 CPU 的平均使用时间
avg(node_cpu_seconds_total) by (mode)

# 按照主机查询各个主机的 CPU 使用率
sum(sum(irate(node_cpu_seconds_total{mode!='idle'}[5m])) / sum(irate(node_cpu_seconds_total [5m]))) by (instance)

六、表量和字符串

除了使用瞬时向量表达式和区间向量表达式以外,PromQL 还直接支持用户使用标量(Scalar)和字符串(String)。
#1.标量(Scalar):一个浮点型的数字值
标量只有一个数字,没有时序。 例如:10	
ps:当使用表达式 count(prometheus_http_requests_total),返回的数据类型,依然是瞬时向量。用户可以通过内置函数scalar()将单个瞬时向量转换为标量。

#2.字符串(String):一个简单的字符串值
直接使用字符串,作为PromQL 表达式,则会直接返回字符串。
"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`

七、合法的 PromQL 表达式

所有的 PromQL 表达式都必须至少包含一个指标名称(例如 http_request_total),或者一个不会匹配到空字符串的标签过滤器(例如{code=”200”})。
因此以下两种方式,均为合法的表达式:
prometheus_http_requests_total # 合 法
prometheus_http_requests_total{} # 合 法
{method="get"} # 合 法

而如下表达式,则不合法:
 {job=~".*"} # 不合法

同时,除了使用 {label=value} 的形式以外,我们还可以使用内置的name标签来指定监控指标名称:
{ name =~"prometheus_http_requests_total"} # 合 法
{ name =~"node_disk_bytes_read|node_disk_bytes_written"} # 合 法

八、PromQL简单运算

使用PromQL 除了能够方便的按照查询和过滤时间序列以外,PromQL 还支持丰富的操作符,用户可以使用这些操作符对进一步的对事件序列进行二次加工。这些操作符包括: 数学运算符,逻辑运算符,布尔运算符等等。

1.简单运算

#1.查询5分钟以内的数据

#2.查询30分钟以前的数据

#3.等于查询

#4.不等于查询

#5.正则匹配

#6.正则取反

#7.计算服务器内存空闲率

#8.计算空闲内存小于1G

#9.计算空闲内存等于一个数字

2.逻辑运算

#1.and 并且

#2.or 或者

#3.unless  排除

3.聚合函数

#1.sum : 求和运算

#2.求最小值

#3.求最大值

#4.求平均数

#5.计算标准差

#6.计算极方差

#7.统计总个数

#8.分类计算个数

#9.获取最小的两个值

#10.获取最大的两个值

#11.求某个位置上的数

4.二进制运算符优先级

对于复杂类型的表达式,需要了解运算操作的运行优先级。例如,查询主机的 CPU 使用率,可以使用表达式:
100 * (1 - avg (irate(node_cpu_seconds_total{mode='idle'}[5m])) by(job) )

其中irate 是PromQL中的内置函数,用于计算区间向量中时间序列每秒的即时增长率。在 PromQL 操作符中优先级由高到低依次为:
^
*,/,%
+, -
==,!=,<=,<,>=,>
and, unless
or

5.特殊查询

#1.查询某个字段

#2.计算范围向量中时间序列的增加

#3.计算范围向量中时间序列的每秒平均平均增长率

#4.计算范围向量中时间序列的每秒平均平均增长率

#5.排序

#6.排序(倒叙)

#7.创建一个新字段

#8.基于范围向量预测从现在开始到某个时间的资源消耗情况

#9.四舍五入(向上)

#10.四舍五入(向下)

posted @ 2021-05-21 17:54  年少纵马且长歌  阅读(252)  评论(0编辑  收藏  举报