当前位置: 首页 > 科技观察

PromQL查询中Rate函数的使用

时间:2023-03-13 16:39:17 科技观察

一般来说,直接画一个原始的Counter类型的指标数据用处不大,因为它们总是会增加的。一般来说,你不会直接关心这个值,因为一旦Counter被重新设置,总计数就没有意义了。比如我们直接执行如下查询语句:demo_api_request_duration_seconds_count{job="demo"},可以得到下图所示的图形:可以看到都在不断增长。一般来说,我们更想知道的是Counter指标的变化率。PromQL提供了不同的函数来计算变化率。rate最常用的用于计算变化率的函数是rate(),rate()函数用于计算指定时间范围内每秒计数器增量的平均数。由于我们正在计算一个时间范围内的平均值,因此我们需要在序列选择器之后添加一个范围选择器。比如我们要计算demo_api_request_duration_seconds_count在最后五分钟每秒的平均变化率,可以使用如下查询语句:rate(demo_api_request_duration_seconds_count[5m])得到如下图:现在绘制的图看起来更有意义是的,在进行速率计算时,会选择指定时间范围内的第一个和最后一个样本进行计算。下图是瞬时计算的计算方法:往往我们需要的是绘制一个图,然后我们需要进行区间查询,指定一个时间范围内进行多次计算,并将结果拼接成一个图:有一个关于rate()和相关函数需要解释的几件事:当捕获的指标进程重新启动时,Counter指标可能会重置为0,但是rate()函数会自动处理这个,它假定Counter指标的值已重置每当它减少时,它就可以调整后续样本,例如,如果时间序列的值为[5,10,4,6],则将其视为[5,10,14,16]。变化率是根据指定时间范围内包含的样本计算得出的。需要注意的是,这个时间窗的边界不一定是样本数据,也不一定是完全对齐的。因此,即使每次Counter增加整数,也有可能计算出的结果是非整数。此外,我们需要注意,当将rate()与聚合运算符(例如sum())或随时间聚合的函数(任何以_over_time结尾的函数)结合使用时,始终首先使用rate()函数,然后进行聚合,否则,当您的目标重新启动时,rate()函数将无法检测到计数器的重置。注意:rate()函数要求指定窗口下至少有两个样本才能计算输出。一般来说,最好选择一个范围窗口大小至少是抓取间隔的4倍,这样即使在窗口对齐或抓取失败的情况下,也有样本可用于计算,例如对于1分钟的抓取间隔,您可以使用4分钟的速率计算,但通常四舍五入为5分钟。所以如果使用query_range进行范围查询,例如在绘图中,那么范围应该至少是步长的大小,否则会丢失一些数据。因为irate使用rate或者increase函数来计算样本的平均增长率,容易陷入长尾问题,无法反映样本数据在时间窗口内的突然变化。例如主机在2分钟的时间窗口内,可能会出现由于流量或其他问题导致CPU占用100%的情况,但无法通过计算时间窗口内的平均增长率来反映该问题.为了解决这个问题,PromQL提供了另一个灵敏度更高的函数irate(vrange-vector)。irate也用于计算区间向量的计算率,但它反映的是瞬时增长率。irate函数通过区间向量中最后两个样本数据计算区间向量的增长率。这种方法可以避免时间窗范围内的长尾问题,表现出更好的灵敏度。irate函数绘制的图标更能反映样本数据的瞬时变化状态。既然最后两个点是用来计算的,为什么还要指定一个类似于[1m]的时间范围呢?这个[1m]不用于计算,irate在计算时最多会在[1m]的范围内找一个点,如果超出[1m]没有找到数据点,则放弃这个点的计算。由于rate()提供更平滑的结果,建议在长期趋势分析或警报中使用rate函数,因为当rate只有短暂的峰值时不应触发警报。使用irate()函数上面的表达式会显示一些短下降图:除了计算每秒的速率外,还可以使用increase()函数查询指定时间范围内的总增加量,基本等价以速率乘以时间范围选择器中的秒数:increase(demo_api_request_duration_seconds_count{job="demo"}[1h])例如,上面表达式的结果和使用rate()函数计算的结果是同样的整体图形趋势,只是Y轴的数据不同而已,一个是数量,一个是百分比。rate()、irate()和increase()函数只能输出非负值的结果。对于跟踪可能上升或下降的值(例如温度、内存或磁盘空间)的指标,delta()和deriv()函数会代替。deriv()函数可以在一个区间向量中计算每个时间序列的二阶导数,使用简单线性回归,deriv(vrange-vector)的参数是一个区间向量,返回一个瞬时向量,这个函数一般只在时间序列的Gauge类型中使用。例如,要计算在15分钟的窗口下每秒磁盘使用率上升或下降了多少:还有一个predict_linear()函数可以预测未来指定时间段内某个Gauge类型指标的值,对于例如,我们可以根据过去15分钟的变化,预测一小时后的磁盘使用情况,可以使用如下表达式查询:predict_linear(demo_disk_usage_bytes{job="demo"}[15m],3600)如果磁盘在几个小时内用完,这个函数可以用来提醒我们。