向量之间的运算试图为左侧向量中的每个条目在右侧向量中找到匹配元素。匹配行为有两种基本类型: 一对一和多对一/一对多。
这些向量匹配关键字允许在提供不同标签集的序列之间进行匹配:
on 关键字用于指定哪些标签在向量匹配时必须相等。例如,如果你有两个时间序列向量,并且你只想匹配那些具有相同 job 标签的时间序列,你可以这样写:
# / 是二元操作符 vector1 / on (job) vector2
这将会匹配 vector1 和 vector2 中所有 job 标签值相同的时间序列。
ignoring 关键字则正好与 on 相反,它指定在向量匹配时哪些标签应该被忽略。这在某些情况下非常有用,比如当两个向量中的时间序列有细微的标签差异,但你仍然希望它们被匹配在一起时。
例如,假设 vector1 中的时间序列有 environment="production" 标签,而 vector2 中的时间序列有 environment="staging" 标签,但你仍然希望这两个向量中的所有时间序列被匹配在一起。你可以这样写:
# / 是二元操作符 vector1 / ignoring (environment) vector2
这将会匹配 vector1 和 vector2 中的所有时间序列,而不考虑它们的 environment 标签值。
注意:在使用 on 和 ignoring 时,必须确保它们后面的括号内是有效的标签名。同时,on 和 ignoring 不能同时在一个向量匹配表达式中使用。
在 PromQL 中,group_left 和 group_right 是连接操作(如 join)中的组修改器(group modifiers)。它们用于确定在连接两个向量时如何处理分组。当你想要根据一个向量中的标签来匹配另一个向量中的时间序列时,这些组修改器就变得非常有用。
group_left 修饰符用于在连接操作时保留左侧向量(left-hand side vector)的所有时间序列,即使右侧向量(right-hand side vector)中没有匹配的时间序列。如果右侧没有匹配的时间序列,则结果中的对应字段将为空。
语法如下:
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
其中,<vector expr> 是向量,<bin-op> 是二元操作符,ignoring 和 on 是匹配关键字。
group_right 修饰符与 group_left 相反。它用于在连接操作时保留右侧向量的所有时间序列,即使左侧向量中没有匹配的时间序列。如果左侧没有匹配的时间序列,则结果中的对应字段将为空。
语法如下:
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
其中,<vector expr> 是向量,<bin-op> 是二元操作符,ignoring 和 on 是匹配关键字。
注意:
(1)group_left 和 group_right 只影响连接操作的结果,它们不会改变原始向量的内容。
(2)分组修饰符只能用于比较和运算,and、unless 和 or 运算默认与右侧向量中所有可能的条目匹配。
一对一操作会从操作的每一方找到一对唯一的条目。默认情况下,操作格式为 vector1 <operator> vector2。如果两个条目具有完全相同的标签和相应值,它们就会匹配。ignoring 关键字允许在匹配时忽略某些标签,而 on 关键字允许将考虑的标签集减少到你提供的标签列表。语法:
<vector expr> <bin-op> ignoring(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) <vector expr>
输入示例:
method_code:http_errors:rate5m{method="get", code="500"} 24 method_code:http_errors:rate5m{method="get", code="404"} 30 method_code:http_errors:rate5m{method="put", code="501"} 3 method_code:http_errors:rate5m{method="post", code="500"} 6 method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600 method:http_requests:rate5m{method="del"} 34 method:http_requests:rate5m{method="post"} 120
查询示例:
method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
这将返回一个结果向量,其中包含在过去 5 分钟内测量的每种方法中状态代码为 500 的 HTTP 请求的比例。没有 ignoring(code),就不会有匹配结果,因为这些指标指标不共享同一组标签(左侧的有 method 和 code 标签,右侧仅有 method 标签)。带有 put 和 del 方法的条目不匹配,也不会显示在结果中:
{method="get"} 0.04 // 24 / 600 {method="post"} 0.05 // 6 / 120
多对一和一对多匹配指的是 "one" 侧的每个向量元素可以与 "many" 侧的多个元素匹配。这必须使用 group_left 或 group_right 修饰符明确请求,其中 group_left/group_right 决定哪个向量具有更高的基数:
<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr> <vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>
在使用组修改器(group_left / group_right)时提供的标签列表包含了来自“one”侧的附加标签,这些标签将被包含在结果指标中。对于 on,标签只能出现在其中一个列表中。结果向量的每个时间序列必须是唯一可识别的。
(1)输入示例数据:
method_code:http_errors:rate5m{method="get", code="500"} 24 method_code:http_errors:rate5m{method="get", code="404"} 30 method_code:http_errors:rate5m{method="put", code="501"} 3 method_code:http_errors:rate5m{method="post", code="500"} 6 method_code:http_errors:rate5m{method="post", code="404"} 21 method:http_requests:rate5m{method="get"} 600 method:http_requests:rate5m{method="del"} 34 method:http_requests:rate5m{method="post"} 120
(2)查询示例:
method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
在这种情况下,左侧向量的每个方法标签值都包含一个以上的条目。因此,我们使用 group_left 来表示。现在,右侧的元素将与左侧具有相同 methods 标签的多个元素相匹配:
{method="get", code="500"} 0.04 // 24 / 600 {method="get", code="404"} 0.05 // 30 / 600 {method="post", code="500"} 0.05 // 6 / 120 {method="post", code="404"} 0.175 // 21 / 120