在 Prometheus 中,PromQL 支持以下内置聚合运算符,这些运算符可用于聚合单个瞬时向量的元素,从而生成具有聚合值的元素较少的新向量:
sum(计算各维度的总和)
min(选择各维度的最小值)
max (选择各维度的最大值)
avg(计算各维度的平均值)
group(结果向量中的所有值均为 1)
stddev(计算各维度的总体标准偏差)
stdvar(计算各维度的总体标准方差)
count (计算向量中元素的个数)
count_values (计算具有相同值的元素个数)
bottomk (样本值最小的 k 个元素)
topk (样本值最大的 k 个元素)
quantile(计算各维度的 φ-quantile (0 ≤ φ ≤ 1))
注意:
(1)count_values 为每个唯一样本值输出一个时间序列。每个序列都有一个附加标签。标签名称由聚合参数给出,标签值是唯一的样本值。每个时间序列的值是该样本值出现的次数。
(2)topk 和 bottomk 与其他聚合器的不同之处在于,结果向量中会返回输入样本的子集,包括原始标签。
(3)quantile 计算 φ-quantile,即在汇总的 N 个维度的指标值中排名第φ*N 的值。例如,quantile(0.5, ...) 计算中位数,quantile(0.95, ...) 计算第 95 个百分位数。如果 φ = NaN,则返回 NaN。对于 φ < 0,返回 -Inf。对于 φ > 1,返回 +Inf。
上述的聚合运算符既可用于对所有标签维度进行汇总,也可通过包含 without 或 by 子句来保留不同的维度。这些子句可以在表达式之前或之后使用。语法如下:
<aggr-op> [without|by (<label list>)] ([parameter,] <vector expression>)
或
<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
其中:
<aggr-op> 是聚合操作符。
<label list> 是一个不带引号的标签列表,可以包含一个逗号,即(label1,label2)和(label1,label2,)都是有效的语法。
parameter 参数仅对 count_values、quantile、topk 和 bottomk 有效。
如果 http_requests_total 指标的时间序列是按 application、instance 和 group 标签划分的,我们就可以通过以下方法计算出所有实例中每个应用程序和每个组的 HTTP 请求总数:
sum without (instance) (http_requests_total)
相当于:
sum by (application, group) (http_requests_total)
如果我们只对所有应用程序的 HTTP 请求总数感兴趣,我们可以简单地写道:
sum(http_requests_total)
要计算每个构建版本运行的二进制文件的数量,我们可以这样写:
count_values("version", build_version)
要获得所有实例中最大的 5 个 HTTP 请求计数,我们可以写道:
topk(5, http_requests_total)
without 关键字用于指定在聚合过程中应该忽略哪些标签。这意味着在聚合结果中,这些标签将不会被包含。这对于消除不需要的标签维度非常有用,尤其是在绘制图表或计算总和时。
示例:假设你有一个 prometheus_http_requests_total 指标时间序列,如下图:
但是,我们只对按 code 标签聚合感兴趣,可以这样写:
sum(prometheus_http_requests_total) without(job,instance,handler)
上述示例将根据 code 标签计算 prometheus_http_requests_total 指标的总和,如下图:
by 关键字用于指定在聚合过程中应该保留哪些标签。与 without 相反,by 确保聚合结果中包含指定的标签。这在需要对特定标签进行分组聚合时非常有用。
示例:假设你有一个 prometheus_http_requests_total 指标时间序列,如下图:
但是,我们只对按 code 标签聚合感兴趣,可以这样写:
sum(prometheus_http_requests_total) by(code)
上述示例将根据 code 标签计算 prometheus_http_requests_total 指标的总和,如下图:
sum(prometheus_http_requests_total) by(code)
如果不使用 without 或 by,Prometheus 默认会在聚合时保留所有标签。如下图:
我们使用 without 和 by 关键字可以帮助你更精细地控制聚合结果的结构和内容。
注意:without 和 by 关键字仅影响聚合函数的行为,不影响原始时间序列的标签。此外,这两个关键字也可以与其他向量匹配操作符(如 on 和 ignoring)结合使用,以实现更复杂的查询和聚合需求。