简介
顾名思义,子查询是一个查询的一部分,它允许你在一个查询中执行范围查询,这在以前是不可能的。这是一个长期存在的功能请求:prometheus/prometheus/1227。
子查询支持的pull request 最近已合并到 Prometheus 中,将在 Prometheus 2.7 中可用。让我们在下面了解更多关于它的信息。
动机
有时,你会希望使用较低分辨率/范围(例如 `5m`)的 `rate` 来发现问题,同时对较高范围(例如 `1h` 的 `max_over_time`)聚合此数据。
以前,对于单个 *PromQL* 查询来说,上述情况是不可能的。如果你想在查询上进行范围选择用于告警规则或绘图,则需要基于该查询创建一个录制规则,并在录制规则创建的指标上执行范围选择。示例:`max_over_time(rate(my_counter_total[5m])[1h])`。
当你想要在跨越数天或数周的数据上获得一些快速结果时,可能需要等待相当长的时间,直到你的录制规则中有足够的数据可以使用。忘记添加录制规则可能会令人沮丧。并且为查询的每个步骤创建录制规则会很繁琐。
有了子查询支持,所有等待和挫败感都被消除了。
子查询
子查询类似于 /api/v1/query_range API 调用,但嵌入在即时查询中。子查询的结果是一个范围向量。
Prometheus 团队在慕尼黑举行的 2018 年 Prometheus 开发峰会上就子查询的语法达成了一致。这些是峰会关于子查询支持的笔记,以及用于实现子查询支持的语法设计文档。
<instant_query> '[' <range> ':' [ <resolution> ] ']' [ offset <duration> ]
-
<instant_query>
等同于/query_range
API 中的query
字段。 -
<range>
和offset <duration>
类似于范围选择器。 -
<resolution>
是可选的,它等同于/query_range
API 中的step
。
当未指定分辨率时,全局评估间隔将作为子查询的默认分辨率。此外,子查询的步长是独立对齐的,并且不依赖于父查询的评估时间。
示例
`min_over_time` 函数内部的子查询以 1 分钟的分辨率,返回过去 30 分钟内 `http_requests_total` 指标的 5 分钟速率。 这等效于 `query=rate(http_requests_total[5m]), end=<now>, start=<now>-30m, step=1m` 的 `/query_range` API 调用,并取所有接收值的最小值。
min_over_time( rate(http_requests_total[5m])[30m:1m] )
分解
-
rate(http_requests_total[5m])[30m:1m]
是子查询,其中 `rate(http_requests_total[5m])` 是要执行的查询。 - `rate(http_requests_total[5m])` 从 `start=<now>-30m` 到 `end=<now>` 执行,分辨率为 `1m`。请注意,`start` 时间与 `1m` 的步长独立对齐(对齐的步长为 `0m 1m 2m 3m ...`)。
- 最后,将以上所有评估的结果传递给 `min_over_time()`。
下面是一个嵌套子查询的示例,以及默认分辨率的用法。最内层的子查询获取 `distance_covered_meters_total` 在一段时间内的速率。我们使用它来获取速率的 `deriv()`,再次在一段时间内。最后取所有导数的最大值。请注意,最内层子查询的 `<now>` 时间是相对于 `deriv()` 上的外部子查询的评估时间的。
max_over_time( deriv( rate(distance_covered_meters_total[1m])[5m:1m] )[10m:] )
在大多数情况下,你需要默认的评估间隔,这是默认情况下评估规则的间隔。自定义分辨率将在你希望减少/增加计算频率的情况下有所帮助,例如,你可能希望减少计算频率的昂贵查询。
结语
尽管子查询使用起来很方便,可以替代录制规则,但过度使用它们会对性能产生影响。为了提高效率,应将繁重的子查询最终转换为录制规则。
也不建议在录制规则内部使用子查询。如果你需要在录制规则中使用子查询,请创建更多的录制规则。