PromQL 快速上手¶
PromQL 是 Prometheus 监控系统监控系统的查询语言,语法简洁且功能强大。与传统 SQL 语言不同,PromQL 的语法结构较为独特。
本文将介绍 PromQL 的常见查询用法。
用 PromQL 选择时间序列¶
在 PromQL 中,选择时间序列非常简单,只需直接写出序列名称即可。例如,以下查询将返回所有名称 node_network_receive_bytes_total
的时间序列:
这个名称对应于 node_exporter metric,它记录了各种网络接口接收的字节数。一个简单的查询可能会返回带有以下标签的时间序列,例如对 eth0
,eth1
和 eth2
网络接口:
node_network_receive_bytes_total{device="eth0"}
node_network_receive_bytes_total{device="eth1"}
node_network_receive_bytes_total{device="eth2"}
不同的标签用大括号括起来,例如 {device="eth0"}
,{device="eth1"}
,{device="eth2"}
。
指标集 Measurement¶
在观测云,所有指标都归属于指标集,我们以指标集为单位管理指标的生命周期。而在 Prometheus 中,是没有指标集 Measurement 这个概念的。在通过 Datakit 上报数据时,可以手动配置 Measurement,或者根据前缀自动生成。
以 node_network_receive_bytes_total
指标为例,假设我们通过 Datakit 自动规则来生成,那么这个指标将会拆分为 Measurement 和 Field 两个部分,分别是 node
和 network_receive_bytes_total
。
在查询时也会有略微改变,继续以不同网络接口为例:
node:network_receive_bytes_total{device="eth0"}
node:network_receive_bytes_total{device="eth1"}
node:network_receive_bytes_total{device="eth2"}
可以观察到,现在的指标名筛选格式变成了 measurement:field
,中间以冒号连接。
按标签过滤¶
单个指标名称可能对应于具有不同标签集的多个时间序列,就像上面的示例一样。如何选择仅匹配 {device="eth1"}
的时间序列?只需在查询中提及所需的标签即可:
如果要选择除 eth1
之外的设备的所有时间序列,只需在查询中将 =
替换为 !=
:
如何选择以 eth
开头的设备的时间序列?只需使用正则表达式即可:
过滤器可以包含与 Go 兼容的任意正则表达式(也称为 RE2)。
要选择不以 eth
开头的设备的所有时间序列,只需将 =~
替换为 !~
:
按多个标签过滤¶
可以组合使用标签过滤器。例如,以下查询将仅返回 eth
开头的设备的 node42:9100
实例上的时间序列:
标签过滤器之间使用 and
运算符组合,即“返回与这个过滤器匹配 and 那个过滤器匹配的时间序列”。如何实现 or
运算符?目前,PromQL 缺乏用于组合标签过滤器的 or
运算符,但在大多数情况下,可以用正则表达式来代替。例如,以下查询将返回 eth1
或 lo
设备的时间序列:
按正则表达式过滤指标或指标集名称¶
指标集和指标名其实是具有特殊名称的普通标签:__measurement__
和 __field__
,因此可以在这些标签上应用正则表达式来过滤你想要的数据。
例如,查询 node
指标集中所有具有 network_receive_bytes_total
或 network_transmit_bytes_total
指标名称的时间序列:
或者查询分布在 node1
和 node2
两个指标集中的 network_receive_bytes_total
或 network_transmit_bytes_total
指标名称的时间序列:
比较当前数据与历史数据¶
PromQL 允许查询历史数据并将其与当前数据组合或比较。只需在查询中添加 offset
。例如,以下查询将返回 node:network_receive_bytes_total
名称的所有时间序列的一周前的数据:
以下查询将返回当前 GC 开销超过一个小时前 GC 开销的 1.5 倍的点:
计算速率¶
您可能会注意到,图表对上面的所有查询都绘制了不断增长的线:
这样的图形的可用性接近于零,因为它们显示的是难以解释的不断增长的计数器值,而我们需要画出网络带宽的图形。PromQL 具有一个函数 rate,它可以为所有匹配时间序列计算每秒速率:
现在这样的图形就可以理解了:
查询中的 [5m]
是什么意思?这是时间持续时间(d)。
在我们的情况下为 5 分钟 — 在计算每个图形点的每秒速率时向后查看。每个点的简化速率计算如下:(Vcurr-Vprev) /(Tcurr-Tprev)
,其中 Vcurr
是当前点的值 -Tcurr
,Vprev
是时间 Tprev = Tcurr-d
上的值。
如果这看起来太复杂,只需记住更高的 d
会平滑图形,而较低的 d
会给图形带来更多噪音。
观测云使用了一种 PromQL 扩展语法 MetricsQL (感谢 VictoriaMetrics 开源!),在此情况下,[d]
可以省略。在这种情况下,它等于图形上两个连续点之间的持续时间(也称为“步长”):
所以当不清楚 rate
后面的持续时间应该如何填写时,请放心直接省略。
rate
的注意事项¶
rate
会去掉指标名称,但会保留内部时间序列的所有标签。
请勿将 rate
应用于可能上下波动的时间序列。这种时间序列称为测量值。rate
必须仅应用于计数器,它们总是上升,但有时可能会重置为零(例如,在服务重新启动时)。
请勿使用 irate
代替 rate
,因为 它不能捕获峰值,而且它并不比 rate
快多少。
算术运算符¶
PromQL 支持所有基本的算术运算:
- 加法(+)
- 减法(-)
- 乘法(*)
- 除法(/)
- 取模(%)
- 指数(^)
这使得可以执行各种转换。例如,将字节/秒转换为位/秒:
此外,这使得可以执行跨时间序列的计算。例如,Flux 查询 可以简化为以下 PromQL 查询:
使用算术运算符组合多个时间序列时,需要了解匹配规则。否则,查询可能会出错或导致不正确的结果。匹配规则的基础很简单:
- PromQL 引擎会从左右两侧的所有时间序列中剥离度量名称,但保留标签;
- 对于左侧的每个时间序列,PromQL 引擎会在右侧搜索具有相同标签集的相应时间序列,对每个数据点应用操作,并返回具有相同标签集的结果时间序列。如果没有匹配项,则从结果中删除该时间序列。
匹配规则可以通过 ignoring
、on
、group_left
和 group_right
修饰符进行增强。虽然这些修饰符的使用较为复杂,但在大多数情况下并不需要使用它们。
PromQL 比较运算符¶
PromQL 支持以下比较运算符:
- 等于(==)
- 不等于(!=)
- 大于(>)
- 大于或等于(>=)
- 小于(<)
- 小于或等于(<=)
这些运算符可以应用于任意 PromQL 表达式,就像算术运算符一样。比较运算的结果是匹配数据点的时间序列。例如,以下查询将仅返回带宽小于 2300 字节/秒的时间序列:
这将导致以下带有间隙的图形,其中带宽超过 2300 字节/秒:
比较运算符的结果可以使用 bool
修饰符增强:
在这种情况下,结果将包含 1 表示 true 的比较和 0 表示 false 的比较:
聚合和分组函数¶
PromQL 允许聚合和分组时间序列。时间序列按给定的标签集进行分组,然后为每个组应用给定的聚合函数。例如,以下查询将返回在所有安装了 node_exporter
的节点上按实例分组的入口流量总和:
使用 Gauges¶
Gauges 是可以随时上下浮动的时间序列,例如内存使用、温度或压力。在为仪表盘绘制图形时,通常需要显示每个点的最小值、最大值、平均值和/或分位数值。PromQL 提供了以下函数来实现这些需求:
例如,以下查询将为图形上的每个点绘制空闲内存的最小值:
MetricsQL 为 PromQL 添加了 rollup_* 函数,当应用于 Gauges 时,可以自动返回 min
、max
和 avg
值。例如:
标签的操作¶
PromQL 提供了两个函数,用于标签的修改、美化、删除或创建:
尽管这些函数的使用较为复杂,但它们允许对所选时间序列的标签进行强大的动态操作。MetricsQL 通过更方便的标签操作函数扩展了这些功能:
label_set
:为时间序列设置额外标签label_del
:从时间序列中删除给定标签label_keep
:除给定标签外,从时间序列中删除所有标签label_copy
:将标签值复制到其他标签label_move
:重命名标签label_transform
:将所有与给定正则表达式匹配的子字符串替换为模板替换label_values
:从给定标签返回数值
从单个查询中返回多个结果¶
有时需要从单个 PromQL 查询返回多个结果。这可以通过 or 运算符来来实现。例如,以下查询将返回所有名称为 metric1
、metric2
和 metric3
的时间序列:
MetricsQL 简化了返回多个结果的过程,只需在 ()
中列举它们:
请注意,任意的 PromQL 表达式都可以放在那里,而不仅仅是指标名称。
在组合表达式结果时,有一个常见的陷阱:具有重复标签集的结果将被跳过。例如,以下查询将跳过 sum(b)
,因为 sum(a)
和 sum(b)
都具有相同的标签集——它们根本没有标签:
结论¶
PromQL 是一种易于使用但功能强大的时间序列数据库查询语言。与 SQL、InfluxQL 或 Flux 相比,它允许以简洁而清晰的方式编写典型的 TSDB 查询。
本教程未涵盖 PromQL 的所有功能,因为有些特性并不是很常用:
你可以使用这个 PromQL 速查表继续学习 PromQL。
本文主体内容翻译自 PromQL tutorial for beginners and humans ,观测云也正在使用 VictoriaMetrics 开源的 MetricsQL 引擎的实现,再次感谢 VictoriaMetrics!