有没有办法在PromQL中表达真正的“左连接”?

问题描述 投票:0回答:1

有什么方法可以用向量匹配来表达相当于PromQL中的SQL“左连接”操作吗?

我想加入信息指标,但即使没有匹配的信息指标,我也想保留非信息指标。如果没有大量重复查询和使用

or
运算符,这似乎是不可能的。如果必须处理多个可能丢失的信息指标,和/或左侧是一个不平凡的表达式,那么复制查询的两个“分支”很快就会变得难以管理。

例如如果我有一个主要指标

important_metric
和一个信息指标
workload_priorities_info
,如果存在匹配的时间序列,我想用
important_metric
中的标签来丰富
workload_priorities_info
。但我想始终保留输出中的
important_metric
系列,无论是否存在匹配。

使用 PromQL 约定加入信息指标(info 函数尚未准备好),如果存在匹配的

important_metric
,将返回
workload_priorities_info
。但如果没有匹配,它会完全忽略
important_metric

important_metric{}
# produce one output series for each LHS input series for which a RHS input series
# with the same (join_labels) exists
* on (join_labels)
  # copy RHS "info_label" label values to the output series
  group_left(info_label)
  # force the value of the input series to use on the RHS to 1, and
  # summarize it to discard any irrelevant labels so we don't encounter errors
  # if there are duplicates due to e.g. workload restarts on the service emitting
  # the info-metric.
  group by (join_labels, info_label) (
    workload_priorities_info{}
  )

这类似于 LHS

INNER JOIN
上的
GROUP BY
important_metric
。我找不到像
LEFT JOIN
这样的方法来表达这一点,其中没有右侧匹配的左侧行保留在输出中。


请注意听起来类似的问题 有没有办法在 PromQL 中执行“左外连接”之类的查询?实际上是要求反连接,这通常表示为带有过滤器的左连接

IS NULL
对于 RHS。所以这不是同一件事。

另请参阅:

prometheus promql
1个回答
0
投票

最佳解决方法:与“or”联合

我最接近的使用集合操作将查询作为两个分支执行 - 一个用于“内部联接”一侧,另一个是反联接,仅返回与右侧不匹配的左侧行。如果 LHS 是一个重要的表达式而不是一个简单的独立度量,那么这会非常冗长,而且效率也很低。

(
  important_metric{}
  * on (join_labels)
    group_left(info_label)
    group by (join_labels, info_label) (
      workload_priorities_info{}
    )
)
# if there's no series on the LHS with the same labels as the RHS after ignoring
# the "info_label" label on each side, add the RHS series to the output, otherwise
# output the LHS series.
or ignoring (info_label)
important_metric{}

有输入

important_metric{join_labels="1"} 100
important_metric{join_labels="2"} 64
important_metric{join_labels="3"} 5

workload_priorities_info{join_labels="1",info_label="highprio"}
workload_priorities_info{join_labels="3",info_label="lowprio"}

这会产生

{join_labels="1",info_label="highprio"} 100
{join_labels="2"} 64
{join_labels="3",info_label="lowprio"} 5

基于 提案:具有默认值或外连接的 PromQL 算术(issue#13625)这可能是当前可能的最佳解决方法。

用于比较的 SQL 类似物

这个的 SQL 翻译会是这样的

# inner join to find rows with matching info metrics
SELECT
  important_metric.value * workload_priorities_info.value,
  important_metric.join_labels,
  workload_priorities_info.info_label
FROM important_metric
INNER JOIN workload_priorities_info USING (join_labels)
# append two sets of rows
UNION ALL
# find rows that do NOT have any matching info-metric and append them to
# the result set
SELECT important_metric.value,
  important_metric.join_labels,
  NULL
FROM important_metric
LEFT JOIN INNER JOIN workload_priorities_info USING (join_labels)
WHERE workload_priorities_info.info_label IS NULL

我们想要的相当于

SELECT
  important_metric.value * coalesce(workload_priorities_info.value, 1),
  important_metric.join_labels,
  workload_priorities_info.info_label
FROM important_metric
LEFT JOIN workload_priorities_info USING (join_labels)
© www.soinside.com 2019 - 2024. All rights reserved.