跳转至

集合操作

有的时候我们需要过滤或将一组时间序列与另一组时间序列进行合并,Prometheus 提供了 3 个在瞬时向量之间操作的集合运算符。

  • and(集合交集):比如对较高错误率触发报警,但是只有当对应的总错误率超过某个阈值的时候才会触发报警
  • or(集合并集):对序列进行并集计算
  • unless(除非):比如要对磁盘空间不足进行告警,除非它是只读文件系统。

union

与算术和过滤二元运算符类似,这些集合运算符会尝试根据相同的标签集在左侧和右侧之间查找来匹配序列,除非你提供 on()ignoring() 修饰符来指定应该如何找到匹配。

注意:与算术和过滤二进制运算符相比,集合运算符没有 group_left()group_right() 修饰符,因为集合运算符总是进行多对多的匹配,也就是说,它们总是允许任何一边的匹配序列与另一边的多个序列相匹配。

对于 and 运算符,如果找到一个匹配的,左边的序列就会成为输出结果的一部分,如果右边没有匹配的序列,则不会输出任何结果。

例如我们想筛选出第 90 个百分位延迟高于 50ms 的所有 HTTP 端点,但只针对每秒收到多个请求的维度组合,查询方式如下所示:

  histogram_quantile(0.9, rate(demo_api_request_duration_seconds_bucket{job="demo"}[5m])) > 0.05
and
  rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) > 1

and 操作

有的时候我们也需要对两组时间序列进行合并操作,而不是交集,这个时候我们可以使用 or 集合运算符,产生的结果是运算符左侧的序列,加上来自右侧但左侧没有匹配标签集的时间序列。比如我们要列出所有低于 10 或者高于 30 的请求率,则可以用下面的表达式来查询:

  rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) < 10
or
  rate(demo_api_request_duration_seconds_count{job="demo"}[5m]) > 30

or 操作

我们可以看到在图中使用值过滤器和集合操作会导致时间序列在图中有断点现象,这取决于他们在图中的时间间隔下是否能够与过滤器进行匹配,所以一般情况下,我们建议只在告警规则中使用这种过滤操作。

还有一个 unless 操作符,它只会保留左边的时间序列,如果右边不存在相等的标签集合的话。

练习:

1.构建一个查询,显示按 path、method、status(5 分钟内平均)划分的 demo API 请求的第 95 个百分位延迟,除非这个维度组合每秒收到的请求少于 1 个请求(5 分钟内平均)。

 histogram_quantile(0.95, sum by(path, method, status, le) (rate(demo_api_request_duration_seconds_bucket[5m])))
unless
 sum by(path, method, status) (rate(demo_api_request_duration_seconds_count[5m])) < 1