topk 与分组聚合是什么
LogQL 在日志查询之上提供了指标类查询能力:把日志行转成数值或计数序列后,再套 sum、avg、count 等聚合运算符,配合 by 子句做分组。topk 属于聚合运算符的一种,用来直接回答「谁排在前列」这类问题,例如哪个服务错误最多、哪条路由最慢。它的输入必须是聚合后的序列,而不是原始日志流。
基本信息
| 适用平台 | Grafana Loki 的 LogQL 指标查询 |
|---|---|
| 典型函数 | rate、count_over_time、quantile_over_time、sum、avg |
| 分组写法 | sum by (标签) (...),标签来自流标签或解析出的字段 |
| topk 形式 | topk(N, 表达式),返回按值排序的前 N 条序列 |
典型使用场景
- 错误排行:各服务错误日志速率的前五名,用于快速判断影响面
- 慢路由定位:按路由分组统计耗时分位,找出长尾接口
- 容量观察:按实例分组看日志量与错误量,发现异常单点
- 发布回归对比:按版本标签分组,确认新版错误率是否上升
- 看板面板数据源:给 Grafana 面板提供即时排名
分组与 TopN
分组与 TopN
# 各服务错误速率的前五名
topk(5, sum by (app) (rate({env="prod"} |= "error" [5m])))
# 按路由统计 P95 耗时(先用 json 解析出数值字段再 unwrap)
avg by (route) (quantile_over_time(0.95,
{app="api"} | json | unwrap duration_ms [5m]))
# 计数类聚合:某关键字每分钟出现次数
sum by (level) (count_over_time({app="api"} |= "error" [1m]))聚合运算符对照
| 运算符 | 用途 | 常见误用 |
|---|---|---|
| sum by | 分组求和,兼容计数器与数值 | 对分位结果再求和没有业务含义 |
| avg by | 分组均值 | 均值会掩盖长尾,延迟类优先看分位 |
| topk / bottomk | 取排名前 N 或后 N | N 太大时图形失去可读性 |
| count_over_time | 窗口内行数计数 | 窗口过短会让曲线剧烈抖动 |
| quantile_over_time | 窗口内分位数 | 分位不可跨组再平均 |
topk 的结果会随时间变化:同一面板上不同时刻的前几名可能不是同一批序列,画成折线会出现序列进进出出的锯齿,日常巡检用即时查询更直观。
分组字段基数过高时排名频繁跳动,也更容易触发序列数上限;先收敛分组维度(如从实例收敛到服务),再做排名。