首页/云/可观测性速查/topk 与 bottomk:找出靠前的序列
Prometheus 与采集64 条

topk 与 bottomk:找出靠前的序列

topk(n, v) 返回分组内数值靠前的 n 条序列,常用于找出错误数偏多的服务或实例;可先按维度分组再对每组取 topk。

可观测性速查云更新于 2026-10-13

topk 与 bottomk 是什么

topk(n, v) 返回分组内数值靠前的 n 条序列,bottomk 相反;常用于找出错误数偏多的服务、耗时最长的接口或容量最紧的实例。它可以对整个结果集取 Top,也可以用 by 子句对每个分组分别取前 n 条。返回的是原始序列及其数值,而不是排名序号或计数,理解这一点才能正确阅读图形。

基本信息

函数签名topk(n, instant-vector) / bottomk(n, instant-vector)
分组写法topk(...) by (label) 每组各取 n 条
输入类型瞬时向量(不能直接吃区间向量)
返回内容原值序列,不是序号或计数
参数 n每组保留的序列条数
适用版本Prometheus 全版本通用

典型使用场景

  • 值班看板找出当前错误数最多的 5 个服务或实例
  • 定位耗时最长的接口,配合 P99 面板下钻
  • 按机房或集群分组,各自取 Top 排查本地异常
  • 容量巡检挑出磁盘或内存水位最紧的若干节点
  • 搭配阈值过滤,先筛异常再排名,缩小展示范围避免噪声
  • 排障时对比 topk 与全量阈值命中,判断是全局问题还是局部问题

全局 Top 与分组 Top

全局 Top 与分组 Top
# 全局:错误数前 5 的序列
topk(5, sum by (instance, service) (rate(http_requests_total{code=~"5.."}[5m])))

# 分组:每个服务内错误数前 3 的实例
topk(3, sum by (service, instance) (rate(http_requests_total{code=~"5.."}[5m]))) by (service)

# 负向:找出内存余量最少的 5 个实例
bottomk(5, node_memory_MemAvailable_bytes)

# 先过阈值再排名,减少无关曲线
bottomk(5, node_filesystem_avail_bytes < 1e10)

常见误读

现象原因正确理解
曲线来回跳topk 是瞬时快照,排名逐点变化属正常,图上看排名更替
条数多于 n按分组后每组各取 n 条总条数 = 分组数 × n
空空无数据底层选择器本身无数据先单独跑内层表达式
值不是整数返回的是原值而非排名序号需要序号得另想办法
topk 是瞬时快照:序列排名会跳变,图形上曲线来回替换属于正常现象,不要当成数据抖动去排查。
要对区间数据排名,先把它聚合成瞬时向量:topk 只能作用于瞬时向量,直接套 [5m] 会报错,通常写成 topk(5, sum by (...) (rate(...[5m])))。
topk 与 sum 的组合顺序会改变结果:先 sum 再 topk 得到聚合后的排名,先 topk 再 sum 语义完全不同,按业务问题决定顺序。

易错点

  • topk 的 n 是每组数量,分组写错会得到与预期不同的曲线条数
  • 对空结果集使用 topk 不会报错,图表空白时先确认底层选择器是否有数据
  • 把区间向量直接传给 topk 会报错,需先用 rate 或 sum 聚合成瞬时向量
  • 排名跳变不适合放进告警表达式做长期判断,告警要先做阈值过滤再考虑排名
  • 大 n 值会让图形塞满曲线、可读性下降,n 一般控制在 5-10 之间

数据来源与参考

  • Prometheus 文档 · topk() / bottomk()
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌