运算符
二元运算符
Prometheus 的查询语言支持基本的逻辑和算术运算符。
对于两个瞬时向量之间的运算,可以修改匹配行为。
算术二元运算符
Prometheus 中存在的以下二元算术运算符:
+
(加法)-
(减法)*
(乘法)/
(除法)%
(取模)^
(幂/指数)
算术运算符在标量/标量、向量/标量以及向量/向量值对之间定义。
在两个标量之间,行为是显而易见的:它们产生另一个标量,该标量是应用运算符到两个标量运算数的结果。
在瞬时向量和标量之间,运算符应用于向量中的每个数据样本的值。例如,如果时间序列瞬时向量乘以2,则结果是另一个向量,在该向量中原始向量的每个样本值都乘以2。元数据名称被丢弃。
在两个瞬时向量之间,在左侧向量的每个元素和右侧向量的匹配元素上应用二元算术运算符。结果被传播到结果向量中,分组标签将成为输出标签集。元数据名称被丢弃。找不到与右侧向量中匹配元素对应项的元素不会出现在结果中。
二元三角运算符
有以下在弧度制下工作的 Prometheus 中的二元三角运算符:
atan2
(基于 https://pkg.go.dev/math#Atan2)
三角运算符允许使用向量匹配在两个向量上进行三角函数计算,这在通常的函数中不可用。它们的行为与算术运算符相同。
二元比较运算符
存在以下二元比较运算符:
==
(等于)!=
(不等于)>
(大于)<
(小于)>=
(大于等于)<=
(小于等于)
比较运算符在标量/标量、向量/标量以及向量/向量值对之间定义。默认情况下,它们可以进行过滤。可以通过提供bool
来修改其行为,这将以值的形式返回0
或1
,而非过滤。
在两个标量之间,必须提供bool
修饰符,并且这些运算符的结果是另一个标量,该标量取决于比较结果是0
(false
)还是1
(true
)。
在瞬时向量和标量之间,这些运算符应用于向量中的每个数据样本的值,比较结果为false
的向量元素从结果向量中删除。如果提供了bool
修饰符,则会将应被删除的向量元素值设置为0
,将应保留的向量元素值设置为1
。如果提供了bool
修饰符,则指标名称会被丢弃。
在两个瞬时向量之间,默认情况下作为过滤器使用,应用于匹配的元素。对于表达式为假或找不到匹配的其他一侧的元素,结果向量中将不会包含该元素,而其他元素则被传播到结果向量中,分组标签成为输出标签集。如果提供了bool
修饰符,则会将应删除的向量元素值设置为0
,将应保留的向量元素值设置为1
,分组标签再次成为输出标签集。如果提供了bool
修饰符,则指标名称会被丢弃。
二元逻辑/集合运算符
仅在瞬时向量之间定义的二元逻辑/集合运算符:
and
(交集)or
(并集)unless
(补集)
vector1 and vector2
结果为包含vector1
和vector2
中具有完全匹配标签集的元素的向量。其他元素被删除。从左侧向量继承元数据名称和值。
vector1 or vector2
结果为包含vector1
的所有原始元素(标签集+值)以及vector2
中所有没有与vector1
中匹配标签集的元素的元素。
vector1 unless vector2
结果为包含vector1
中没有与vector2
中任何一个元素完全匹配标签集的元素所形成的向量。两个向量中的匹配元素都被删除。
向量匹配
向量之间的运算尝试在右侧向量中的每一项中找到与左侧向量中每一项相匹配的元素。匹配行为有两种基本类型:一对一和多对一/一对多。
向量匹配关键词
这些向量匹配关键词允许在具有不同标签集的系列之间进行匹配,提供:
on
ignoring
提供的标签列表将决定向量如何结合。示例可以在一对一向量匹配和多对一和一对多向量匹配中找到
组修饰符
这些组修饰符允许多对多对一/一对多向量匹配:
group_left
group_right
可以提供给组修饰符的标签列表包含来自“一”边(the “one” side)的标签,这些标签将被包含在结果指标中。
多对一和一对多匹配是高级用例,应谨慎考虑。通常,正确地使用ignoring(<labels>)
就_可以提供所需的结果_
组修饰符只能用于比较和算术。运算如and
、unless
和or
默认情况下会与右侧向量的所有可能条目进行匹配。
一对一向量匹配
一对一在运算符的两侧查找唯一的配对项。默认情况下,这是一类遵循格式vector1 <operator> vector2
的运算。如果它们具有完全相同的标签集和相应的值,则两个条目匹配。ignoring
关键字允许在匹配时忽略某些标签,而on
关键字则将考虑的标签集减少到提供的列表:
输入示例:
查询示例:
这个返回一个结果向量,其中包含过去5分钟内每个方法的状态代码为500的 HTTP 请求的比例。如果没有ignoring(code)
,则不会有匹配,因为这些指标不会共享相同的标签集。put
和del
方法没有匹配,不会出现在结果中:
多对一和一对多向量匹配
多对一和一对多匹配指的是“一边”的每一项都可以与“多边”的多项进行匹配的情况。这必须明确地通过使用group_left
和group_right
修饰符,以确定哪个向量具有更高的基数。
提供的标签列表与组修饰符一起使用包含来自“一个”方面的额外标签,这些标签将被包含在结果指标中。对于on
,一个标签只能出现在列表中的一个位置。结果向量中的每个时间序列都必须是唯一可识别的。
查询示例:
在这种情况下,左侧向量包含method
标签值的多项条目。因此,我们使用group_left
指示这种情况。右侧元素现在与左侧具有相同method
标签的多个元素进行匹配:
聚合运算符
Prometheus 支持以下原生聚合运算符,可用于聚合单个瞬时向量的元素,生成具有聚合值的新向量,元素数量较少:
sum
(计算维度上的总和)min
(选择最小值维度)max
(选择最大值维度)avg
(计算维度上的平均值)group
(结果向量中的所有值为1)stddev
(计算维度上的总体标准差)stdvar
(计算维度上的总体方差)count
(计算向量中元素的数量)count_values
(计算相同值的元素数量)bottomk
(样本值最小的 k 个元素)topk
(样本值最大的 k 个元素)quantile
(计算维度上的 φ-分位数(0 ≤ φ ≤ 1))limitk
(采样 n 个元素)limit_ratio
(如果r > 0
则采样大约 r 比例的元素,如果r = -(1.0 - r)
则采样剩余元素)
这些运算符既可以用于在所有标签维度上进行聚合,也可以通过包括without
或by
子句来保留不同的维度。这些子句可以在表达式之前或之后使用。
或者
label list
是一个未引号的标签列表,可能包含尾随逗号,即(label1, label2)
和(label1, label2,)
都是有效的语法。
without
从结果向量中移除列出的标签,同时保留输出中的其他标签。by
的行为相反,它丢弃不在by
子句中列出的标签,即使它们在向量的所有元素中具有相同的标签值也是如此。
parameter
只有在count_values
、quantile
、topk
、bottomk
、limitk
和limit_ratio
中需要。
count_values
为每个唯一样本值输出一个时间序列。每个序列都有一个额外的标签:该标签名称由聚合参数给出,标签值是唯一的样本值。每个时间序列的值是该样本值出现的次数。
topk
和bottomk
与其他聚合器不同,因为返回的是输入样本的子集,其结果向量中包括原始标签。by
和without
只用于对输入向量进行分桶。
limitk
和limit_ratio
也返回输入样本的子集,原始标签被包含在结果向量中,这些都是实验功能,必须通过标志--enable-feature=promql-experimental-functions
启用。
quantile
计算 φ-分位数,即在聚合维度上的 N 指标值中排名为 φ*N 的值。φ 作为聚合参数。例如,quantile(0.5, ...)
计算中位数,quantile(0.95, ...)
计算第95百分位数。对于 φ = NaN
,返回NaN
。对于 φ < 0,返回-Inf
。对于 φ > 1,返回+Inf
。
示例:
假设指标http_requests_total
是在application
、instance
和group
标签上扇出的时间序列,我们可以计算所有实例中每个应用和组的 HTTP 请求总数:
这与:
等价。
如果我们只关心看到的所有应用程序中的总 HTTP 请求数,我们可以简单地写出:
要计算每个构建版本运行的程序数量,我们可以写出:
要获取所有实例中最大的5个 HTTP 请求计数,我们可以写出:
为了采样10个时间序列,例如检查标签及其值,我们可以写出:
为了确定性地采样大约 10% 的时间序列,我们可以写出:
由于limit_ratio()
实现了一个基于标签哈希的确定性采样算法,你可以通过使用:
获取上述样本的补集,即大约90%。这可以同样精确地获取limit_ratio(0.1, ...)
返回的那些元素。
你还可以使用此功能检查两个样本子集的平均值之间的差异与标准差相比是否“小”,以验证avg()
是否是样本值的代表性聚合,
二元运算符优先级
以下列表展示了 Prometheus 中二元运算符的优先级,从最高到最低。
^
*
,/
,%
,atan2
+
,-
==
,!=
,<=
,<
,>=
,>
and
,unless
or
相同优先级的运算符是左结合的。例如,2 * 3 % 2
等同于(2 * 3) % 2
。然而,^
是右结合的,因此2 ^ 3 ^ 2
等同于2 ^ (3 ^ 2)
。
Prometheus 原生 Histogram 运算符
原生 Histogram(native Histogram)是一个实验性功能。要通过特性标志启用从 Histogram 中消费数据。一旦从 Histogram 中消费数据,即使特性标志已经被禁用,也可以查询这些数据。然而,原生 Histogram 的运算支持仍然非常有限。
逻辑/集合二元运算符在涉及 Histogram 样本时表现正常。它们仅检查向量元素的存在,并不会根据元素的样本类型(浮点或 Histogram )改变其行为。count
聚合运算符工作原理类似。
Prometheus 完全支持二元+
和-
运算符之间的两个原生 Histogram 以及用于聚合原生 Histogram 的sum
和avg
聚合运算符。即使涉及的 Histogram 具有不同的桶布局,桶会自动适当地转换以执行运算(在当前支持的分桶方案下,这总是有可能的)如果任何运算需要聚合混合的 Histogram 样本和浮点样本,则输出向量中的对应元素将被完全移除。
在任何顺序下,*
运算符在原生 Histogram 与浮点数之间工作,而/
运算符仅在特定顺序下在原生 Histogram 与浮点数之间使用。
所有其他运算符(上述运算符未提及的情况)在有意义的场景下表现均不佳。它们要么将 Histogram 样本视为值为0的浮点样本,或者(在标量与向量之间的算术运算的情况下)保持 Histogram 样本不变。在原生 Histogram 成为稳定功能之前,这种行为将改变为有意义的行为。
该文档基于 Prometheus 官方文档翻译而成。