PromQL 查询中如何按标签分组聚合?
PromQL 用 by 子句按标签分组聚合:sum by (status) (http_requests_total)。本文讲解 by/without 的用法、多标签分组、常见聚合函数搭配,以及分组后的高基数注意事项。
用 by 子句:sum(http_requests_total) by (status)——把指标按 status 标签的每个取值聚成一条线;反向操作用 without,保留除列出标签外的所有标签。
基本语法
# 按状态码分组统计 QPS
sum(rate(http_requests_total[5m])) by (status)
# 按多个标签分组
sum(rate(http_requests_total[5m])) by (status, method)
# without:去掉 instance 维度,其余标签保留
sum(rate(http_requests_total[5m])) without (instance)
常用聚合函数搭配
sum by (...):总量分布,如各状态码的请求量;avg by (...):平均值,如各机房的平均延迟;max by (...)/min by (...):极值监控;count by (...):统计每个标签值下有多少条序列,常用来数实例数;topk(3, ...):取最高的 3 条,看"最忙的接口"。
注意事项
- rate 要放在 sum 里面:
sum(rate(x[5m])),先算每条序列的速率再聚合,顺序反了结果是错的; - 分组的标签越多线条越多:按 user_id 这类高基数标签分组会产生上万条序列,查询慢且图表不可读——生产分组维度控制在几十个取值以内;
- by 里没有的标签会被丢弃,聚合结果只保留 by 列出的标签。
观测云对照
观测云的 DQL 查询同样支持按任意标签分组聚合,且在指标查看器中是点选式操作——选指标、选分组标签、选聚合方式即可出图,不需要手写查询语句。
常见问题(FAQ)
Q:by 和 without 能一起用吗? 不能,一个聚合表达式里二选一。
Q:分组后标签值太多图上看不清? 用 topk 只保留头部,或先在采集侧精简标签。
Q:能按标签值的正则分组吗? 先用 label_replace() 把正则提取的片段写成新标签,再按新标签 by。