PromQL的一些整理

发布时间 2023-04-06 19:00:46作者: GaoYanbing

PromQL简介
PromQL(Prometheus Query Language)是Prometheus 提供的函数式查询语言,可以查询实时数据和聚合时间序列的数据。在数据可视化和编写告警规则中使用。

PromQL的表达式类型
瞬时向量(Instant-Vector) - 一组时间序列,包含相同时间戳的单个样本;

例如:http_requests_total

可以通过向 {} 里附加一组标签来进一步过滤:http_requests_total{group="res"}

完全匹配和正则匹配

= : 选择与提供的字符串完全相同的标签。
!= : 选择与提供的字符串不相同的标签。
=~ : 选择正则表达式与提供的字符串(或子字符串)相匹配的标签。
!~ : 选择正则表达式与提供的字符串(或子字符串)不匹配的标签
区间向量(Range-Vector) - 一组时间序列,包含每个时间序列随时间变化的数据点范围,例如:http_requests_total[5m]在过去5分钟内指标名称为http_requests_total的所有时序

s - 秒
m - 分钟
h - 小时
d - 天
w - 周
y - 年
标量(Scalar) - 一个简单的数字浮点值,例如:count(http_requests_total)

字符串(String) - 一个简单的字符串值;

时间位移操作:在瞬时向量表达式和区间向量表达式中,都是以时间为基准的:

使用offset 可以查询前一段时间的数据
如:rate(http_requests_total[5m] offset 1w)
Prometheus的指标类型
Prometheus有四个指标类型

Counter:计数器,单调递增;
Gauge:仪表盘,可增可减的数据;
Histogram:直方图,将时间范围内的数据划分成不同的时间段,并各自评估其样本个数及样本值之和,因而可计算出分位数;
可用于分析因异常值而引起的平均值过大的问题;

分位数计算要使用专用的histogram_quantile函数;

Summary:类似于Histogram,但客户端会直接计算并上报分位数;
Counter 计数器

Counter是累计值需要借助于rate、irate、topk和increase等函数来生成样本数据的变化状况(增长率);

rate

它主要用于计算时间范围内某指标的速率

rate(v range-vector)计算范围向量中时间序列的每秒平均增长率

rate(http_requests_total[2h])
irate

作用与rate函数一致,但它计算的点不会使用时间窗口所有的点。而是直接使用最后两个点。

irate(v range-vector)计算范围向量中时间序列的每秒增加率。这是基于最后两个数据点

irate(http_requests_total[2h])
rate与irate对比

irate适合快速变化的计数器(counter)

rate适合缓慢变化的计数器(counter)

increase

表示一个时间窗口的变化值

resets

用于计算一个时间窗口被重置的次数,采样值有减小就加一

topk

topk(k, Instant vector) 获取样本值最大的 k 个元素

获取该指标下http请求总数排名前3的时间序列;

topk(3, http_requests_total)
Gauge 仪表盘

Gauge用于存储其值可增可减指标的样本数据,通常用于进行求和、平均值、最小值、最大值等聚合计算;也会结合PromQL的predict_linear和delta函数使用;

predict_linear(v range-vector, t scalar) 函数可以预测范围向量v在t秒后的值,它通过线性回归的方式来预测样本数据的Gauge变化趋势;

predict_linear(mysql_up[5m],10)
delta(v range-vector) 函数计算范围向量中每个时间序列元素的第一个值与最后一个值之差,从而展示不同时间点上的样本值的差值;

delta(http_requests_total[5m])
PromQL查询例子
Prometheus 存储的是时序数据,它的时序是由指标名称和标签组成。

一个简单的查询相当于是对各种标签的筛选,例如:

mysql_global_status_commands_total{instance="10.83.10.21",command="select"} # 表示查询名字为 mysql_global_status_commands_total,command 为 "select" 的数据

mysql_global_status_commands_total{instance="10.83.10.21",command!="select"} # 表示查询 command 不为 "select" 的数据
查询条件支持正则匹配,例如:

mysql_global_status_commands_total{instance="10.83.10.21",command=~"select|update|delete|insert"} # 表示查询 command 为 "select|update|delete|insert" 的数据

mysql_global_status_commands_total{instance="10.83.10.21",command=~"se.*"} # 表示查询 command 为 "se" 开头的数据

mysql_global_status_commands_total{instance="10.83.10.21",command!~"se.*"} # 表示查询 command 不为 "se" 开头的数据
PromQL计算
二元运算符
PromQL支持基本的算术运算、比较运算和逻辑运算,这类运算支持使用操作符连接两个操作数,因而也称为二元运算符。

算术运算

支持的运算符:+(加)、-(减)、*(乘)、/(除)、%(取模)和^(幂)

比较运算

支持的运算符:==(等值比较)、!=(不等)、>、<、>=和<=(小于等于)

逻辑运算

支持的运算符:and(并且)、or(或者)和unless(除了)

二元运算符优先级

下面的列表显示了 Prometheus 中二元运算符的优先级,从高到低。

^
*, /, %
+, -
==, !=, <=, <, >=,>
and, unless
or
聚合运算符
Prometheus 支持以下内置聚合运算符,可用于聚合单个即时向量的元素,从而生成具有聚合值的更少元素的新向量:

sum (计算维度的总和)
min (选择最小值)
max (选择最大值)
avg (计算维度上的平均值)
group (分组)
stddev (标准差)
stdvar (方差)
count (数量)
count_values (计算具有相同值的元素个数)
bottomk (样本值的最小 k 个元素)
topk (样本值最大的 k 个元素)
quantile (在维度上计算 φ-分位数 (0 ≤ φ ≤ 1))
PromQL与 SQL 对比
下面以 Prometheus 收集的 http_requests_total 指标数据为例子来对比。

基本查询对比
查询当前所有数据
// PromQL

http_requests_total



// MySQL

SELECT * from http_requests_total WHERE created_at BETWEEN 1495435700 AND 1495435710;
条件查询
// PromQL

http_requests_total{code="200", handler="prometheus"}



// MySQL

SELECT * from http_requests_total WHERE code="200" AND handler="prometheus" AND created_at BETWEEN 1495435700 AND 1495435710;
模糊查询: code 为 2xx 的数据
// PromQL

http_requests_total{code=~"2.."}



// MySQL

SELECT * from http_requests_total WHERE code LIKE "2__" AND created_at BETWEEN 1495435700 AND 1495435710;
比较查询: value 大于 100 的数据
// PromQL

http_requests_total > 100



// MySQL

SELECT * from http_requests_total WHERE value > 100 AND created_at BETWEEN 1495435700 AND 1495435710;
范围区间查询: 过去 5 分钟数据
// PromQL

http_requests_total[5m]



// MySQL

SELECT * from http_requests_total WHERE created_at BETWEEN 1495435410 AND 1495435710;
聚合查询对比
count 查询: 统计当前记录总数
// PromQL

count(http_requests_total)



// MySQL

SELECT COUNT(*) from http_requests_total WHERE created_at BETWEEN 1495435700 AND 1495435710;
sum 查询: 统计当前数据总值
// PromQL

sum(http_requests_total)



// MySQL

SELECT SUM(value) from http_requests_total WHERE created_at BETWEEN 1495435700 AND 1495435710;
avg 查询: 统计当前数据平均值
// PromQL

avg(http_requests_total)



// MySQL

SELECT AVG(value) from http_requests_total WHERE created_at BETWEEN 1495435700 AND 1495435710;
top 查询: 查询最靠前的 3 个值
// PromQL

topk(3, http_requests_total)



// MySQL

SELECT * from http_requests_total WHERE created_at BETWEEN 1495435700 AND 1495435710 ORDER BY value DESC LIMIT 3;