写点什么

Prometheus 查询操作符(二) 向量匹配

用户头像
耳东@Erdong
关注
发布于: 刚刚

向量与向量之间进行运算操作时会基于默认的匹配规则:依次找到与左边向量元素匹配(标签完全一致)的右边向量元素进行运算,如果没找到匹配元素,则直接丢弃。


接下来将介绍在 PromQL 中有两种典型的匹配模式:一对一(one-to-one),多对一(many-to-one)或一对多(one-to-many)。

一对一向量匹配

一对一的向量匹配会从操作符的每一边表达式找到一对唯一的样本值。在默认情况下,这是遵循vector1 <operator> vector2 格式的操作。


在操作符两边表达式标签不一致的情况下,可以使用 on(label list)或者 ignoring(label list)来修改便签的匹配行为。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"}  24method_code:http_errors:rate5m{method="get", code="404"}  30method_code:http_errors:rate5m{method="put", code="501"}  3method_code:http_errors:rate5m{method="post", code="500"} 6method_code:http_errors:rate5m{method="post", code="404"} 21
method:http_requests:rate5m{method="get"} 600method:http_requests:rate5m{method="del"} 34method:http_requests:rate5m{method="post"} 120
复制代码


下面我们看一个查询的例子。


method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m
复制代码


这该表达式会返回在过去 5 分钟内,HTTP 请求状态码为 500 的在所有请求中的比例。如果没有使用 ignoring(code),操作符两边表达式返回的瞬时向量中将找不到任何一个标签完全相同的匹配项。


同时由于 method 为 put 和 del 的样本找不到匹配项,因此不会出现在结果当中。


{method="get"}  0.04            //  24 / 600{method="post"} 0.05            //   6 / 120
复制代码

一对多或者多对一向量匹配

多对一和一对多匹配是指“一”上的每个向量元素都可以与“多”上的多个元素匹配。这必须使用 group_leftgroup_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>
复制代码


多对一和一对多两种模式一定是出现在操作符两侧表达式返回的向量标签不一致的情况。因此需要使用 ignoring 和 on 修饰符来排除或者限定匹配的标签列表。


method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m
复制代码


该表达式中,左向量 method_code:http_errors:rate5m 包含两个标签 method 和 code。而右向量 method:http_requests:rate5m 中只包含一个标签 method,因此匹配时需要使用 ignoring 限定匹配的标签为 code。 在限定匹配标签后,右向量中的元素可能匹配到多个左向量中的元素 因此该表达式的匹配模式为多对一,需要使用 group 修饰符 group_left 指定左向量具有更好的基数。


最终的运算结果如下:


{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
复制代码


多对一和一对多匹配是应该仔细考虑的高级用例。通常,正确使用 ignoring(<labels>) 可以得到预期的结果。

发布于: 刚刚阅读数: 2
用户头像

耳东@Erdong

关注

还未添加个人签名 2020.05.24 加入

主要研究分享运维技术,专注于监控、CICD、操作系统、云原生领域,公众号【耳东学堂】,知识星球同名,坚持原创,希望能和大家在运维路上结伴而行 邮箱:erdong@mail.erdong.site

评论

发布
暂无评论
Prometheus 查询操作符(二) 向量匹配