菜单
开源

Grafana Mimir 查询引擎

Mimir 查询引擎 (MQE) 是 Prometheus 查询引擎的一个实验性替代方案。您可以在 querier 中使用它来评估 PromQL 查询。

MQE 生成的结果与 Prometheus 引擎等效,通常比 Prometheus 引擎使用的内存和 CPU 更少,并且评估查询的速度至少与 Prometheus 引擎一样快(甚至更快)。它支持几乎所有稳定的 PromQL 功能,并对使用不受支持功能的查询透明地回退到 Prometheus 引擎。

如何启用 MQE

MQE 是实验性的,默认禁用。要启用它,请在 querier 上设置 -querier.query-engine=mimir CLI 标志,或设置等效的 YAML 配置文件选项。

回退到 Prometheus 引擎

默认情况下,对于任何使用不受支持功能的查询,MQE 都会回退到 Prometheus 引擎。

要禁用此行为,请在 querier 上设置 -querier.enable-query-engine-fallback=false CLI 标志,或设置等效的 YAML 配置文件选项。如果回退被禁用,并且 MQE 收到的查询不受支持,则查询将失败。

要强制 MQE 支持的查询使用 Prometheus 引擎,请在查询请求中添加 X-Mimir-Force-Prometheus-Engine: true HTTP 头部。此头部仅在回退启用时生效。

查询内存消耗限制

MQE 支持对每个查询强制执行内存消耗限制。这可以确保单个内存密集型查询不会独占 querier 中的大部分可用内存,或导致其耗尽所有可用内存并崩溃。

在评估查询时,MQE 估计查询消耗的内存(例如用于最终结果和任何中间计算的内存),如果估计值超过配置的限制,则会停止查询并返回 err-mimir-max-estimated-memory-consumption-per-query 错误。

该估计基于当前为查询评估而保存在内存中的样本所消耗的内存。这包括从数据块解码的原始样本,以及作为计算中间结果或最终结果保存在内存中的样本。它还包括其他一些用于中间结果的大量内存消耗源。

此估计存在以下限制

  • 它不考虑时间序列标签消耗的内存。
  • 它不考虑当前在内存中的数据块消耗的内存。但是,最大数据块数和最大数据块字节数限制仍然会强制执行。
  • 它对每个原生直方图消耗的内存做出了假设,而不是准确计算每个直方图消耗的内存。

默认情况下,不强制执行任何限制。要为所有租户配置默认限制,请设置 -querier.max-estimated-memory-consumption-per-query CLI 标志,或设置等效的 YAML 配置文件选项。您可以通过为特定租户设置 max_estimated_memory_consumption_per_query 来覆盖此默认限制。将限制设置为 0 会禁用它。

对于通过 Prometheus 引擎运行的查询,不强制执行此限制;如果 MQE 被禁用或查询回退到 Prometheus 引擎,则设置此限制无效。

与 Prometheus 引擎的已知差异

以下是 MQE 与 Prometheus 引擎之间的已知差异

不产生时间序列的二元运算

如果 MQE 可以根据两侧时间序列的标签确定二元运算(如 +-/and)不会产生时间序列,则会跳过评估两侧的数据。

例如,如果查询是 foo / bar,并且 foo 选择了单个时间序列 foo{env="test"}bar 选择了单个时间序列 bar{env="prod"},则此查询不会产生任何时间序列,因此不会评估两侧的数据。

这会产生一些明显的副作用,包括

  • querier 可能会记录 aborted stream because query was cancelled: context canceled: query execution finished,因为从 ingester 和 store-gateway 流式传输数据会在未读取全部数据的情况下中止,因为它不需要全部数据。

  • 某些注释不会被发出。例如,如果上面的查询是 rate(foo[1m]) / sum(rate(bar[1m])),Prometheus 引擎会发出诸如 metric might not be a counter, name does not end in _total/_sum/_count/_bucket: "foo"metric might not be a counter, name does not end in _total/_sum/_count/_bucket: "bar" 的注释。相比之下,MQE 不会发出这些注释,因为它们只在评估时间序列数据时发出,而不是在评估时间序列标签时发出。

  • 如果匹配组在一侧没有时间序列但在另一侧有多个时间序列,并且这些时间序列的样本相互冲突,MQE 不会返回 found duplicate series for the match group 错误。

topkbottomk

如果不同时间序列的样本具有相同的值,MQE 和 Prometheus 引擎对于使用 topkbottomk 的查询会产生不同的结果。在这种情况下,Prometheus 引擎的行为不是确定性的,并且在每次评估查询时会选择不同的时间序列。MQE 的实现与 Prometheus 引擎不同,这也可能导致不同的结果。