有什么方法可以用向量匹配来表达相当于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。所以这不是同一件事。
另请参阅:
我最接近的使用集合操作将查询作为两个分支执行 - 一个用于“内部联接”一侧,另一个是反联接,仅返回与右侧不匹配的左侧行。如果 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 翻译会是这样的
# 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)