PromQL
PromQL 函数的入参和返回值的类型:
-
瞬时数据 (Instant vector): 包含一组时序,每个时序只有一个点,例如:
http_requests_total
http_requests_total{job="prometheus"} -
区间数据 (Range vector): 包含一组时序,每个时序有多个点,时间范围通过时间范围选择器
[]
进行定义。例如:http_requests_total[5m]
除了使用m表示分钟以外,PromQL的时间范围选择器支持其它时间单位:
-
s - 秒
-
m - 分钟
-
h - 小时
-
d - 天
-
w - 周
-
y - 年
-
Range Vector 基本上只是为了给函数用的,Grafana 绘图只能接受 Instant Vector。
PromQL操作符
时间位移操作
在瞬时向量表达式或者区间向量表达式中,都是以当前时间为基准
如果我们想查询 5 分钟前的瞬时样本数据,或昨天一天的区间内的样本数据,可以使用位移操作,位移操作的关键字为 offset。
# 查询 5 分钟前的最新数据
http_request_total{} offset 5m
# 往前移动 1 天,查询 1 天前的数据
# 例如现在是 2020-10-07 00:00:00
# 那么这个表达式查询的数据是:2020-10-05 至 2020-10-06 的数据
http_request_total{}[1d] offset 1d
算术运算符
+ (加法)
- (减法)
* (乘法)
/ (除法)
% (求余)
^ (幂运算)
布尔运算符
== (相等)
!= (不相等)
> (大于)
< (小于)
>= (大于等于)
<= (小于等于)
prometheus_http_requests_total > 20
将所有 value 值超过 20 的数据都筛选了出来,value 的值还是具体的数值。但如果我们希望对符合条件的数据,value 变为 1。不符合条件的数据,value 变为 0。那么我们可以使用bool修饰符。
prometheus_http_requests_total > bool 20
逻辑运算符
and,or,unless(排除)
在PromQL操作符中优先级由高到低依次为:
-
^
-
*, /, %
-
+, -
-
==, !=, <=, <, >=, >
-
and, unless
-
or
聚合运算符
Prometheus 还提供了聚合操作符,这些操作符作用于瞬时向量。可以将瞬时表达式返回的样本数据进行聚合,形成一个新的时间序列。目前支持的聚合函数有:
-
sum (求和)
-
min (最小值)
-
max (最大值)
-
avg (平均值)
-
stddev (标准差):标准差(Standard Deviation)常用来描述数据的波动大小。
-
stdvar (标准方差)
-
count (计数)
-
count_values (对value进行计数)
-
bottomk (后n条时序)
-
topk (前n条时序)
-
quantile (分位数)
Label标签匹配操作符
= label等于
!= label不等于
=~ label正则匹配
!~ label正则不匹配
匹配模式详解
向量与向量之间进行运算操作时会基于默认的匹配规则:依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行运算,如果没找到匹配元素,则直接丢弃。
接下来将介绍在PromQL中有两种典型的匹配模式:一对一(one-to-one),多对一(many-to-one)或一对多(one-to-many)
例如存在样本
method_code:http_errors:rate5m{method="get", code="500"} 24
method_code:http_errors:rate5m{method="get", code="404"} 30
method_code:http_errors:rate5m{method="put", code="501"} 3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21
method:http_requests:rate5m{method="get"} 600
method:http_requests:rate5m{method="del"} 34
method:http_requests:rate5m{method="post"} 120
一对一匹配
一对一匹配模式会从操作符两边表达式获取的瞬时向量依次比较并找到唯一匹配(标签完全一致)的样本值
在操作符两边表达式标签不一致的情况下,可以使用on(label list)或者ignoring(label list)来修改便签的匹配行为。
ignoreing可以在匹配时忽略某些便签,on则用于将匹配行为限定在某些便签之内。
method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
该表达式会返回在过去5分钟内,HTTP请求状态码为500的在所有请求中的比例。
如果没有使用ignoring(code),操作符两边表达式返回的瞬时向量中将找不到任何一个标签完全相同的匹配项。
多对一和一对多
多对一和一对多两种匹配模式指的是“一”侧的每一个向量元素可以与”多”侧的多个元素匹配的情况。
使用group修饰符:group_left或者group_right来确定哪一个向量具有更高的基数(充当“多”的角色)。
多对一和一对多两种模式一定是出现在操作符两侧表达式返回的向量标签不一致的情况。因此需要使用ignoring和on修饰符来排除或者限定匹配的标签列表。
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
该表达式中,左向量method_code:http_errors:rate5m
包含两个标签method和code。而右向量method:http_requests:rate5m
中只包含一个标签method,因此匹配时需要使用ignoring限定匹配的标签为code。 在限定匹配标签后,右向量中的元素可能匹配到多个左向量中的元素 因此该表达式的匹配模式为多对一,需要使用group修饰符group_left指定左向量具有更好的基数。
Prometheus内置函数
rate 增长率
rate(v range-vector) 函数:用来求指标的平均变化速率 该函数通常用来求某个时间区间内的请求速率,也就是我们常说的 QPS,注意 rate 函数只是算出来了某个时间区间内的平均速率,没办法反映突发变化
rate = 指定时间范围内的所有数据点 / 时间范围
使用场景
-
实时监控:通过计算时间序列的速率,可以实时监控系统指标的变化速率,例如请求速率、数据流量等。
-
性能分析:分析系统或服务的响应时间、吞吐量等的变化速率,帮助识别和解决性能瓶颈。
-
容量规划:根据系统负载的变化速率进行容量规划和资源调度,以确保系统稳定和高效运行。
irate 瞬时变化率
irate(v range-vector) 同样用于计算区间向量的计算率,但是其反应出的是瞬时增长率
irate = 指定时间范围内的最近两个点的差 / 最后两个样本点的时间
使用场景
-
实时监控:通过计算即时增长率,可以实时监控系统指标的变化速率,例如请求速率、流量变化等。
-
异常检测:检测数据的瞬时变化率,发现异常或突发事件,及时触发警报和应对措施。
-
性能分析:分析系统或服务的响应时间、吞吐量等即时变化情况,进行性能优化和调整。
irate 和 rate
-
irate函数相比于rate函数提供了更高的灵敏度,不过当需要分析长期趋势或者在告警规则中,irate的这种灵敏度反而容易造成干扰。因此在长期趋势分析或者告警中更推荐使用rate函数。
-
当将
irate、rate
函数与 -
既然是使用最后两个点计算,这里又为什么需要
[1m]
呢?这个[1m]
不是用来计算的,是用来限制找 t-2 个点的时间的,比如,如果中间丢了很多数据,那么显然这个点的计算会很不准确,irate
在计算的时候会最多向前在[1m]
找点,如果超过[1m]
没有找到数据点,这个点的计算就放弃了。
聚合运算符
avg min max count sum 接收的参数是瞬时向量
通过 sum
运算符可以将所有的值聚合,可以配合 by
和 without
函数在 sum
的时候,基于某些标签分组(类似 group by
)
PromQL 中的聚合操作语法格式可采用如下面两种格式之一:
-
<聚合函数>(向量表达式) by|without (标签名称列表)
-
<聚合函数> by|without (标签名称列表) (向量表达式)
without用于从计算结果中移除列举的标签,而保留其它标签。
by 结果向量中只保留列出的标签,其余标签则移除。
delta与idelta
delta(v range-vector) :参数是一个区间向量,返回一个瞬时向量。它计算一个区间向量 v 的第一个元素和最后一个元素之间的差值。
idelta(v range-vector) :参数是一个区间向量, 返回一个瞬时向量。它计算最新的 2 个样本值之间的差值。(当区间内仅有一个向量时无返回值)
这两个函数一般只用在 Gauge 类型的时间序列上。
bottomk与topk
bottomk (样本值最小的 k 个元素)、topk (样本值最大的k个元素,和bottomk正好相反,用法一致)
vector
经常会遇到配置的函数查不到数据,我们又希望提供默认值,这样就有趋势图了,那么我们可以使用vector(0)。
(sum(rate(robot_engine_exception_total[1m]))/ sum(rate(robot_engine_request_total[1m]))) OR vector(0)
increase
increase(v range-vector) 函数获取区间向量中的第一个和最后一个样本并返回其增长量,它会在单调性发生变化时(如由于采样目标重启引起的计数器复位)自动中断。
stddev (标准差)
stddev (标准差),常用来描述数据的波动大小。
predict_linear
predict_linear(v range-vector, t scalar) ,预测Gauge指标变化趋势,可以预测时间序列v在t秒后的值。它基于简单线性回归的方式,对时间窗口内的样本数据进行统计,从而可以对时间序列的变化趋势做出预测
predict_linear(node_filesystem_free{job="node"}[2h], 4 * 3600) < 0
histogram_quantile
Summary直接在客户端计算了数据分布的分位数情况
参考
https://prometheus.fuckcloudnative.io/di-san-zhang-prometheus/di-4-jie-cha-xun/functions
https://www.bookstack.cn/read/prometheus-book/README.md
https://www.kawabangga.com/posts/4408