开始使用PromQL
首先
这篇文章是根据 Prometheus 的 “QUERING PROMETHEUS” 一章进行的日本语翻译,并结合了 Prometheus 入门的内容以及实际尝试的内容进行了补充。
更具实际应用价值的例子可以在《Kubernetes(GKE)实用小技巧:便捷的Prometheus技巧集》一书中找到。
PromQL 是一种查询语言。
PromQL(Prometheus Query Language)是用于获取和聚合Prometheus时间序列数据的查询语言。
查询结果可以在Prometheus的表达式浏览器中以表格形式或图表形式进行显示。
当使用像Grafana这样的图表绘制工具进行图表显示时,我们会使用查询语言来向Prometheus发送查询请求。
以下是中文的同义短语:
度量衡
Prometheus所参考的时序数据称为指标(metric)。
例如,表征内存使用量的 process_resident_memory_bytes 就是一个指标。
通常情况下,对于某个度量指标,存在多个时间序列数据。例如,度量指标 process_resident_memory_bytes 可能会有 Prometheus 的内存使用量和主机的内存使用量这两个时间序列数据。
数据类型
PromQL 可处理的数据类型包括以下几种。
-
- Instant vector
-
- Range vector
-
- Scalar
- String
即时向量是一种类似于内存使用量的时序数据。
范围向量是过去一段时间内即时向量值的聚合数据,从某个时间点开始计算。
标量和字符串指的是不是时序的简单值,比如1和”string”。
可以在图表中显示的是即时向量,其他数据类型则用于在计算值或在特定时间段内汇总值时使用。
時系列数据选择器
公式
最简单的选择器形式是使用指标名称。
例如,process_resident_memory_bytes将选择所有具有”进程驻留内存字节”指标的即时向量。

上面的是在 Prometheus 的 Grafana 浏览器中展示 process_resident_memory_bytes 的图形结果。可以看到选择了具有两个标签的 instant vector:{instance=”localhost:9100″, job=”node”} 和 {instance=”localhost:9090″, job=”prometheus”}。
标签匹配器(基本版)
用标签来过滤指标的部分被称为标签匹配器。
如果我们正在提取 Prometheus 进程(job=”prometheus”)和主机(job=”node”)的两个内存使用量,那么可以通过使用 process_resident_memory_bytes{job=”node”} 来获取仅主机的内存使用量。

在这个例子中,{job=”node”} 是一个标签匹配器。
只有标签的 job 完全匹配 “node” 的数据才能被过滤出来。
你也可以使用正则表达式来匹配 “n” 开头的任何工作。
在这种情况下,比如指定了 hoge=”” ,将会选择所有不存在标签 hoge 的时间序列数据。
标签匹配器(应用)
标签匹配器可以应用于指标名称。
由于 metric 名称内部附有 __name__ 标签,因此可以为该标签指定匹配器以选择多个 metric。例如,使用 {__name__=~”.*_count”},可以选择以 _count 结尾的多个 metric。
无效的选择器
在选择时序数据时,需要指定指标名称或无标签匹配的标签选择器。
因此,如果未指定指标名称为 {job=~”.*”} 或者 {hoge=””},则在表达式浏览器中会显示错误。
执行查询时出错:Y:X:解析错误:向量选择器必须包含至少一个非空匹配器。
范围向量选择器
区间向量是在某个时间点到过去一段时间内的实例向量值聚集的数据。
在这段时间内 [1m] 表示为类似的方式,并且这是一个范围向量选择器。
可用的单位如下所示。
s – seconds
m – minutes
h – hours
d – days
w – weeks
y – years
如果在表达式浏览器中显示 process_resident_memory_bytes[1m],将显示以下数据。
(由于范围向量无法在图表中显示,因此需要在控制台选项卡中查看)。

117702656 @1595670231.989
117702656 @1595670246.991
117702656 @1595670261.991process_resident_memory_bytes{instance=”localhost:9100″,job=”node”}22122496 @1595670213.37
22122496 @1595670228.369
22122496 @1595670243.368
22122496 @1595670258.368
可以看出,该值被赋予了一个时间戳为~@1595670216.99的值。
在一个Range vector中,数值的形式是Value @ Value被抓取的时间。
这里有4个数值是因为抓取间隔被设置为15秒,所以在1分钟内获取了4次值。
Range vector 的用途包括了例如了解每小时的平均内存使用量等。
※ 有关详细信息,请参阅 Range vector 的聚合函数。
偏移修饰符 zhě)
偏移修饰符是指将Instant vector或Range vector的时间向过去推移指定的时间量的修饰符。
<instant_query / sub_query> offset <duration>
如果使用 `process_resident_memory_bytes offset 1m`,那么前1分钟的`process_resident_memory_bytes`的值将会显示为当前时间。
从图表上看,如果没有指定offset,指定offset后会将其向右偏移1分钟。
换句话说,对于时间序列数据,每个时间点上都会加上由offset指定的值的影像。
使用偏移修饰符的情况包括在需要确定进程是否重新启动时,比较过去和现在的进程启动时间等。详细请参考示例。
子查询
通过在返回即时向量的查询中添加子查询,可以将查询转换为指定时间范围和指定分辨率的范围向量。
<instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
在以下场景中可以使用子查询:当需要知道在过去1天内进程重新启动了多少次时。
※详细信息请参考示例。
评论 (Paraphrase: 评论)
PromQL 支持注释功能。
# This is a comment
操作员
数学运算符
+ (addition)
– (subtraction)
* (multiplication)
/ (division)
% (modulo)
^ (power/exponentiation)
这些运算符的行为取决于左侧和右侧的数据类型。
-
- 只需一个选项,以下是中文的原生解释:
当两个操作数都是标量 (` `) 时,它的行为是如何的。
当一个操作数是瞬时向量,另一个操作数是标量 (` `) 时,它的行为是如何的。
当两个操作数都是瞬时向量 (` `) 时,它的行为是如何的。
当两侧为标量的情况下的行为
对于两个标量值,将进行算术运算。
举例来说,1加1等于2。
当一个边是瞬时向量,另一个边是标量时的行为。
即时向量的所有时间点的值都与标量值进行算术运算。
如果以 process_resident_memory_bytes / 1000 作为例,那么内存使用量将以 KB 而非字节作为单位。
当左右两边为瞬时向量时的行为。
对于左侧每个时间序列数据,将对与右侧匹配的元素执行算术操作。
从时间序列数据中得出的结果将删除指标名称,并为用于算术分组的标签添加到结果中。
例如,假设以 node_filesystem_avail_bytes 乘以 100 再除以 node_filesystem_size_bytes ,可以计算出磁盘使用率。
比较运算符
== (equal)
!= (not-equal)
> (greater-than)
< (less-than) >= (greater-or-equal)
<= (less-or-equal)
这些运算符的行为取决于左侧和右侧的数据类型。
-
- 当两边都是标量时的行为(<标量> <算术二元运算符> <标量>)
-
- 当一边是瞬时向量,另一边是标量时的行为(<瞬时向量> <算术二元运算符> <标量>)
- 当两边都是瞬时向量时的行为(<瞬时向量> <算术二元运算符> <瞬时向量>)
无论哪种情况,基本行为都是过滤,但是通过在比较运算符后加上 bool 可以将值变为0或1。
(如果比较结果为假,则为0;如果为真,则为1)
<comparison_binary_operator> [bool]
当两边为标量时的行为
必须添加bool。
例如,当1 == 布尔值1时,结果为1;当1 != 布尔值1时,结果为0。
当一个边是瞬时向量,另一边是标量时的行为。
比较将在即时向量的所有时间点上进行,只有真值保留下来,假值将被删除。
如果把 process_resident_memory_bytes 设定为 89.1MB(即89.1 * 1000 * 1000),只有内存使用量大于89.1MB的时候才会被过滤掉。

当两边都是“即时向量”时的行为
在向量匹配中,对于进行匹配的元素进行比较。
逻辑运算符 / 集合运算符
-
- and (intersection)
-
- or (union)
- unless (complement)
这些运算符只能在瞬时向量之间使用。
在instant_vector1和instant_vector2的结果中,只有与instant_vector1的元素完全匹配以及与instant_vector2的元素的标签集完全匹配的元素会被保留下来。在这种情况下,指标名称和值将保留为instant_vector1的。
或者 的结果由 的所有元素以及 的元素中不具有与 匹配的标签集的元素组成。
除非 的结果是从 的元素中删除了与 元素和标签集匹配的部分。
在矢量匹配中,将对匹配的元素进行比较。
向量匹配
对于两个向量的操作,会查找匹配右侧元素的左侧元素。
匹配操作有两种行为:一对一匹配和一对多/多对一匹配。
一对一 (yī duì yī)
一对一的情况下,对每个标签进行标签匹配,匹配成功的标签将被匹配。
可以通过在on上对标签列表进行限制来忽略在ignoring上的标签。
<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>
请参考 Examples 来了解详情。
N对1 / 1对N
在N对1/1对N中,将某个标签进行分组,对其他所有标签进行标签匹配,找出匹配的标签。
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
请参考 Examples 来获取详细信息。
集約修飾子 means “intensive modifier” in Chinese.
sum (calculate sum over dimensions)
min (select minimum over dimensions)
max (select maximum over dimensions)
avg (calculate the average over dimensions)
group (all values in the resulting vector are 1)
stddev (calculate population standard deviation over dimensions)
stdvar (calculate population standard variance over dimensions)
count (count number of elements in the vector)
count_values (count number of elements with the same value)
bottomk (smallest k elements by sample value)
topk (largest k elements by sample value)
quantile (calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions)
这些修饰符仅适用于即时向量。
如果没有指定「by」,结果中的所有标签都会被丢失。
对于通过指定标签进行过滤的元素,「by」会对它们分别进行聚合。
对于通过指定除了某个标签以外的其他标签进行过滤的元素,「without」会对它们分别进行聚合。
<aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>)
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
函数
在中文中,有定义了针对即时向量(instant vector)、范围向量(range vector)和标量执行处理的函数。
请参考此处的函数列表。
数学函数
解析函数
集合向量的聚合函数
avg_over_time(range-vector): the average value of all points in the specified interval.
min_over_time(range-vector): the minimum value of all points in the specified interval.
max_over_time(range-vector): the maximum value of all points in the specified interval.
sum_over_time(range-vector): the sum of all values in the specified interval.
count_over_time(range-vector): the count of all values in the specified interval.
quantile_over_time(scalar, range-vector): the φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.
stddev_over_time(range-vector): the population standard deviation of the values in the specified interval.
stdvar_over_time(range-vector): the population standard variance of the values in the specified interval.
排序函数
判断函数
补助系统函数
例子
在可实施的例子中,Kubernetes(GKE)和便利的Prometheus小技巧集被介绍。
内存使用量
process_resident_memory_bytes
节点重新启动的发生与否
changes(node_boot_time_seconds[1m])
磁盘可用空间的比例
node_filesystem_avail_bytes * 100 / node_filesystem_size_bytes
气温
node_hwmon_temp_celsius * ignoring(label) group_left(label) node_hwmon_sensor_label
CPU的I/O等待比率
sum without(cpu)(rate(node_cpu_seconds_total{mode="iowait"}[5m])) # 1
/ ignoring(mode) # 2
sum without(mode, cpu)(rate(node_cpu_seconds_total[5m])) # 3
1的结果中包含了标签mode.
{实例=”localhost:9100″,作业=”node”,模式=”iowait”}:1.9954526794454766
第三个结果中不包含标签“mode”。
{实例=”localhost:9100″,任务=”节点”}:1.998273690267743
因此,在使用「そのため」進行计算时,需要使用「ignoring」来排除mode标签。
结果不包括模式标签。
在一个小时内, 平均负载超过1的次数。
count_over_time((node_load1 > 1)[1h:])
考试准备
你怎么样检查度量标准?
让我们来研究一下出口商的规格要求。
如果已经有一个构建好的Prometheus,我们可以通过查看Targets来确定使用了哪个Exporter。