如何在Prometheus中对范围向量执行瞬时向量操作?
Prometheus范围向量与瞬时操作的解决方案
首先明确:不能直接对范围向量执行瞬时向量操作,但可以通过子查询实现类似“遍历范围向量中每个瞬时点执行瞬时逻辑”的效果,完美解决你统计时间占比的需求。
你的需求的正确查询方式
要统计过去1小时内,count_containers至少有一个容器的时间占比,正确的查询应该是:
avg(avg_over_time((count_containers > 0)[1h:1m]))
解释下各部分的作用:
(count_containers > 0):先对每个瞬时点的指标值做判断,得到布尔结果(满足条件为1,不满足为0),这是一个瞬时向量。[1h:1m]:将上述瞬时向量转换为范围向量,覆盖过去1小时,步长为1分钟(可根据精度需求调整步长,比如10s)。avg_over_time(...):计算这个范围向量的平均值,结果就是单条时间序列在1小时内满足条件的时间占比。avg(...):如果有多个count_containers时间序列(比如不同实例),最后用avg求所有序列的平均占比。
为什么你的原查询报错
原查询avg(avg_over_time(count_containers[1h] > 0))的问题在于:count_containers[1h]是范围向量,Prometheus不支持直接对范围向量做>0这种瞬时比较操作——必须先把范围向量拆解为单个瞬时点处理,子查询就是干这个的。
类似map的替代方案
Prometheus没有专门的map()函数,但子查询就相当于对范围向量中的每个瞬时元素执行指定的瞬时逻辑,和map的作用一致。另外,如果你是做数值转换类的操作,也可以用clamp_min、clamp_max这类函数,但针对布尔判断场景,子查询是最直接的方式。
另一种等价实现方式
你也可以用sum_over_time和count_over_time的比值来计算占比,效果和avg_over_time完全一致:
avg(sum_over_time((count_containers > 0)[1h:]) / count_over_time((count_containers > 0)[1h:]))
这里sum_over_time统计满足条件的时间点总数,count_over_time统计总时间点数,两者相除就是占比。
内容的提问来源于stack exchange,提问作者user835943
相关产品推荐
相关产品推荐

