【博客486】prometheus-----rate,irate,increase的原理

article/2025/9/29 7:49:53

prometheus-----rate,irate,increase的原理

三者综合比较

这三个函数接受的都是 Range Vector,返回的是 Instant Vector,比较常用。

区别:

rate计算指定时间范围内:增量/时间范围;
irate计算指定时间范围内:最近两个点的增量/最近两个点的时间差;

场景:

irate适合计算快速变化的counter,它可以反映出counter的快速变化;
rate适合计算缓慢变化的counter,它用平均值将峰值削平了(长尾效应);

1、increase()

increase(v range-vector) 函数获取区间向量中的第一个和最后一个样本并返回其增长量,它会在单调性发生变化时(如由于采样目标重启引起的计数器复位)自动中断。

例如,以下表达式返回区间向量中每个时间序列过去 5 分钟内 HTTP 请求数的增长数:

increase(http_requests_total{job="apiserver"}[5m])

该函数配合counter数据类型使用,它的返回值类型只能是计数器类型。

此函数和 rate() 完全一样,只是它没有将最终单位转换为 “每秒”(1/s)。每个规定的采样周期就是它的最终单位。
例如:increase(http_requests_total[5m]) 得出的是5分钟的采样周期内处理完成的HTTP请求的总增长量(单位1/5m)。因此increase(foo[5m])/ (5 * 60) 等同于rate(foo[5m])。

2、rate()

rate(v range-vector) 函数可以直接计算区间向量 v 在时间窗口内平均每秒增长速率,它会在单调性发生变化时(如由于采样目标重启引起的计数器复位)自动中断。
该函数配合counter数据类型使用,它的返回值类型只能用计数器,在长期趋势分析或者告警中推荐使用这个函数。该函数的返回结果不带有度量指标,只有标签列表。

例如,以下表达式返回区间向量中每个时间序列过去 5 分钟内 HTTP 请求数的每秒增长率:

rate(http_requests_total[5m])结果:
{code="200",handler="label_values",instance="120.77.65.193:9090",job="prometheus",method="get"} 0
{code="200",handler="query_range",instance="120.77.65.193:9090",job="prometheus",method="get"}  0
{code="200",handler="prometheus",instance="120.77.65.193:9090",job="prometheus",method="get"}   0.2
...

当将 rate() 函数与聚合运算符(例如 sum())或随时间聚合的函数(任何以 _over_time 结尾的函数)一起使用时,必须先执行 rate 函数,然后再进行聚合操作,
否则当采样目标重新启动时 rate() 无法检测到计数器是否被重置。

计算方法:

取时间范围内的firstValue和lastValue;
变化率 = (lastValue - firstValue) / Range;

在这里插入图片描述

若要计算一段时间内的结果:

对每个数据点,计算(value - valueBeforeRange)/range;

最终得到一串数据,绘制变化率图形;

在这里插入图片描述

当抓取指标的进程重启时,counter可能会重置为0,rate()认为指标值只要减少了就认为被重置了,然后它会自动进行调整。

3、irate()

irate(v range-vector) 函数用于计算区间向量的增长率,但是其反应出的是瞬时增长率。

irate 函数是通过区间向量中最后两个两本数据来计算区间向量的增长速率,它会在单调性发生变化时(如由于采样目标重启引起的计数器复位)自动中断。
这种方式可以避免在时间窗口范围内的“长尾问题”,并且体现出更好的灵敏度,通过irate函数绘制的图标能够更好的反应样本数据的瞬时变化状态。

例如,以下表达式返回区间向量中每个时间序列过去 5 分钟内最后两个样本数据的 HTTP 请求数的增长率:

irate(http_requests_total{job="api-server"}[5m])

irate 只能用于绘制快速变化的计数器,在长期趋势分析或者告警中更推荐使用 rate 函数。
因为使用 irate 函数时,速率的简短变化会重置 FOR 语句,形成的图形有很多波峰,难以阅读。

当将 irate() 函数与聚合运算符(例如 sum())或随时间聚合的函数(任何以 _over_time 结尾的函数)一起使用时,必须先执行 irate 函数,然后再进行聚合操作,
否则当采样目标重新启动时 irate() 无法检测到计数器是否被重置。

irate函数相比于rate函数提供了更高的灵敏度,不过当需要分析长期趋势或者在告警规则中,irate的这种灵敏度反而容易造成干扰。因此在长期趋势分析或者告警中更推荐使用rate函数。

需要注意的是使用rate或者increase函数去计算样本的平均增长速率,容易陷入“长尾问题”当中,其无法反应在时间窗口内样本数据的突发变化。 例如,对于主机而言在2分钟的时间窗口内,可能在某一个由于访问量或者其它问题导致CPU占用100%的情况,但是通过计算在时间窗口内的平均增长率却无法反应出该问题。

为了解决该问题,PromQL提供了另外一个灵敏度更高的函数irate(v range-vector)。irate同样用于计算区间向量的计算率,但是其反应出的是瞬时增长率。irate函数是通过区间向量中最后两个样本数据来计算区间向量的增长速率。这种方式可以避免在时间窗口范围内的“长尾问题”,并且体现出更好的灵敏度,通过irate函数绘制的图标能够更好的反应样本数据的瞬时变化状态。

使用rate计算快速变化的样本平均增长率时,容易陷入长尾问题,因为它用平均值将峰值削平了,无法反映时间窗口内样本数据的快速变化。
与rate类似,irate同样可以计算counter的平均增长率,但其反映出的是瞬时增长率。

Counter类型的监控指标其特点是只增不减,在没有发生重置(如服务器重启,应用重启)的情况下其样本值应该是不断增大的

irate计算增长率时,使用指定时间范围内的最后两个样本数据:

在这里插入图片描述

用grafana做了一个试验,创建一个测试的dashboard, 分别用 irate 和 rate 来监控CPU使用率指标,时间间隔分别用10m, 5m, 2m, 1m 。其中间隔为10分钟的表达式如下:

sum(irate(process_cpu_seconds_total[10m])) * 100sum(rate(process_cpu_seconds_total[10m])) * 100

下图是间隔10分钟的结果,可以看到,irate的曲线比较曲折,而rate的曲线相对平缓:

在这里插入图片描述

4、irate是取最后两个点去计算的,为什么irate还需要时间区间呢

比如:irate(node_network_receive_packets_total{device=~”en.*”}[1m])

因为只用最后两个点的差值来计算,会比 rate 平均值的方法得到的结果,变化更加剧烈,更能反映当时的情况。那既然是使用最后两个点计算,这里又为什么需要 [1m] 呢?这个 [1m] 不是用来计算的,是用来限制找 t-2 个点的时间的,比如,如果中间丢了很多数据,那么显然这个点的计算会很不准确,irate 在计算的时候会最多向前在 [1m] 找点,如果超过 [1m] 没有找到数据点,这个点的计算就放弃了。

5、是不是我们总是使用 irate 比较好呢

也不是,比如 requests/s 这种,如果变化太剧烈,从面板上你只能看到一条剧烈抖动导致看不清数值的曲线,而具体值我们是不太关心的,我们可能更关心一天中的 QPS 变化情况;但是像是 CPU,network 这种资源的变化,使用 irate 更加有意义一些。

6、查看一个函数的功能以及是接收instant-vector还是range-vector:

https://prometheus.io/docs/prometheus/latest/querying/functions/

7、rate 必须在 sum 之前

rate 必须在 sum 之前。Prometheus 支持在 Counter 的数据有下降之后自动处理的,比如服务器重启了,metric 重新从 0 开始。这个其实不是在存储的时候做的,比如应用暴露的 metric 就是从 2033 变成 0 了,那么 Prometheus 就会忠实地存储 0. 但是在计算 rate 的时候,就会识别出来这个下降。但是 sum 不会,所以如果先 sum 再 rate,曲线就会出现非常大的波动。

sum by (job)(rate(http_requests_total{job="node"}[5m]))  # This is okayrate(sum by (job)(http_requests_total{job="node"})[5m])  # Don't do this

Even if you’ve worked around this being invalid expression with a recording rule, the real problem is what happens when one of the servers restarts. The counters from the restarted server will reset to 0, the sum will decrease, which will then be treated by rate as a counter reset and you’d get a large spurious spike in the result.
即使您已经使用记录规则解决了这个无效表达式,真正的问题是当其中一台服务器重新
启动时会发生什么。重新启动的服务器中的计数器将重置为 0,总和将减少,然后将被速率视为计数器重置,您会在结果中得到一个很大的虚假峰值。

同样的道理:

rate(counter_a[5m] + counter_b[5m])        # Don't do thisrate(counter_a[5m]) + rate(counter_b[5m])  # This is okay

The only mathematical operations you can safely directly apply to a counter’s values are rate, irate, increase, and resets
唯一可以安全地直接应用于计数器值的数学运算是 rate、irate、increase 和 resets


http://chatgpt.dhexx.cn/article/FHF7s39T.shtml

相关文章

【博客650】irate适用于绘制细粒度灵敏图,但警惕用于告警

irate适用于绘制细粒度灵敏图,但警惕用于告警 1、irate解析 作用: irate(v range-vector) 函数用于计算区间向量的增长率,但是其反应出的是瞬时增长率。 原理: irate 函数是通过区间向量中最后两个两本数据来计算区间向量的增长…

git查看用户名和密码

一、查看 查看用户名 :git config user.name 查看密码: git config user.password 查看邮箱:git config user.email 查看配置信息: $ git config --list 二、修改 修改用户名 git config --global user.name “xxxx(新的用户名)”…

Linux中git保存用户名密码

Linux下命令行使用git,每次操作都要输入用户名和密码很麻烦,可以通过配置保存用户名和密码。 进入到git项目的根目录下,打开.git目录下的config文件 cd .git vim config添加如下内容 [credential]helper store:wq保存退出 执行上述操作之…

git设置单个仓库用户名以及密码

有些时候我们的服务器可能要部署多个git仓库,不同git仓库的用户名以及密码都是不一样的,此时需要我们设置单个仓库的用户名以及密码。 1.git设置用户名以及邮箱 命令如下: git config user.name "userName" //你的用户名 …

git 修改用户名和密码

windows 在控制面板修改凭证就可以进行修改用户名密码。 Linux 执行vim ~/.git-credentials,可以看到被保存的账号密码,删掉、修改或新增都可以! eg:http://账号:密码git仓库http地址或用https://账号:密码git仓库http地址 h…

mac下git设置用户名密码

设置用户名和邮箱 git config --global user.name [username] git config --global user.email [email] 查看用户名和邮箱 git config --global user.name git config --global user.email 查看配置文件 git config --list 编辑配置文件 vi .gitconfig sourcetree中的…

linux 分配git用户名和密码,配置Git记住用户名密码的俩种方法

前言 相信大家在使用github过程中,也有这情况,总是让大家输入烦人的用户名,密码,浪费时间。下面这俩种办法也是网上找来的,我做了些整合,避免大家走入当时跟我一样的坑中。 方法一 1.1创建文件储存git用户名…

git重新设置用户名密码

设置密码 我们输入git config --global user.name "youname"设置密码,在输入git config --global user.email "aaqq.com"设置邮箱

git设置用户名、密码和邮箱(全局设置)

(1)git设置用户名(如下图一): git config --global user.name Urasaki (2)git设置密码(如下图一): git config --global user.password Am100100 &#xff…

设置git账户名和密码

git config --global user.email [email] //邮箱 git config --global user.name [username] //密码查看是否配置成功 git config --list出现user.email和user.name表示配置成功

git设置账户名密码

最近新创建了一个项目,同步git代码,但是每次连接远程都要重新输入用户名密码信息,很烦,就想着怎么让他记住账号。就用了以下方法,亲测有效,分享记录下。 一. 打开当前项目下.git文件夹,找到con…

git记住用户名和密码

在使用git时,如果用的是HTTPS的方式,则每次提交,都会让输入用户名和密码,久而久之,就会感觉非常麻烦,那么该如何解决呢? 方式一:使用SSH,添加ssh key。 方式二&#xf…

git设置用户名密码(单用户和多用户)

刚换电脑重头配置git,写篇文章纪念一下。 一、前言 Git共有三个级别的config文件,分别是system、global和local。global的在$home\.gitconfig,local的在仓库目录下的.git\config。这三个级别都分别配置了用户信息,当git commit时…

JS的 execCommand 方法实现一个简单的富文本编辑器

一、document.execCommand() 从其名字上可以看出execCommand()是用来执行命令的,当一个HTML文档切换到设计模式时,document暴露 execCommand方法,该方法允许运行命令来操纵可编辑内容区域的元素。如保存文件、打开新文件、撤消、重做、剪切…

用c语言,制作一个心形彩色告白图案(附源码)

今天我们来一个好玩的&#xff0c;用c语言&#xff0c;制作一个心形彩色告白图案。 送给c语言初学者 代码&#xff1a; #include<stdio.h> #include<math.h> #include<windows.h> #include<time.h> #define u 0.1 #define v 0.053 void setcolor(uns…

ASP.NET 2.0中使用Gridview控件的高级技巧

ASP.NET 2.0中&#xff0c;新增加的gridview控件的确十分强大&#xff0c;弥补了在asp.net 1.1中&#xff0c;使用datagrid控件时的不足之处。因为在asp.net 1.1中&#xff0c;在使用datagrid时&#xff0c;很多情况下依然要编写大量的代码&#xff0c;十分不方便&#xff0c;而…

C# winform中,简单实现Listview.Subitem.BackColor.ForeColor改变字体颜色,Listview.Subitem.BackColor 改变背景

做项目的时候,客户的查询结果中要在listview中亮显查询关键字.在网上找了半天,没有合适的代码.于是就自己琢磨了一下.贴出代码,希望对大家有所帮助. 注意事项&#xff1a; 一定要把listview的OwnerDraw属性设置为True&#xff08;默认是False&#xff09;。 当设置Owner…

Button 设置ForeColor不生效问题

Button 设置ForeColor不生效问题 在C#设计界面的时候出现的一个问题&#xff0c;在将button 的属性Enable设置为False后&#xff0c;无论你设置的ForeColor为什么颜色&#xff0c;结果都只有一种颜色。 如下图&#xff1a; button1&#xff0c;属性如下&#xff1a; BackCo…

Winform中自定义控件,BackColor,ForeColor系统选择窗口

/// <summary>/// 正常时的前景色&#xff0c;若不设置&#xff0c;以ForeColor为准/// </summary>private Color _normalForeColor Color.Empty;[Category("自定义外观"),//DispId(NativeMethods.ActiveX.DISPID_FORECOLOR),DISPID_FORECOLOR uncheck…