💫《博主主页》:
🔎 IF Club社区主页__奈斯、
🔥《擅长领域》:擅长阿里云AnalyticDB for MySQL(分布式数据仓库)、Oracle、MySQL、Linux、prometheus监控;并对SQLserver、NoSQL(Redis)有了解
💖如果觉得文章对你有所帮助,欢迎点赞收藏加关注💖

哈喽各位,今天继续带来 Prometheus 监控的分享......如标题所示,今天这篇文章要聊的是 PromQL 查询语法中的 rate() 和 irate() 函数。对于已经了解这两个函数的小伙伴们应该知道,这两个函数都是处理 计数器(Counter)类型指标 的核心函数,用于计算时间序列的增长率(即每秒速率)🚀。但是很多刚接触 Prometheus 的小伙伴经常会把这两个函数搞混,博主在这方面做了大量的实验和测试,今天就来分享一下关于这两个函数的实战经验。😊
有些大佬应该已经了解过这两个函数,那么读完这篇文章之后相信一定会有一些新的收获和启发;而对于还不太明白的小伙伴们,阅读完后相信就不会再迷茫了!👍
prometheus+Grafana全系列文章(实时更新🔥):
目录
-
- [了解rate([]) 和 irate([])函数:](#了解rate([]) 和 irate([])函数:)
- [对比rate([]) 和 irate([])函数:](#对比rate([]) 和 irate([])函数:)
- 生产配置演示:rate([1m])、rate([10m])和irate([1m])、irate([10m])
了解rate([]) 和 irate([])函数:
函数 rate([]) irate([]) 计算方式 基于 时间窗口内所有数据点 计算 平均增长率 基于 最后两个数据点 计算 瞬时增长率 平滑性 结果平滑,适合长期趋势分析 对短期波动敏感,适合捕捉突增 推荐窗口 通常 ≥ 5m(如 [5m]) 通常 ≤ 5m(如 [1m]) 适用场景 监控持续增长率(如 QPS、流量) 调试瞬时异常(如 CPU 突增)
对比rate([]) 和 irate([])函数:
我们监控一个HTTP服务的请求计数器 http_requests_total,已知:
- 采集间隔: 15秒(prometheus.yml文件中的scrape_interval参数)
- 时间窗口: 1分钟(包含5个数据点)
- 原始数据如下:
时间点 时间偏移 累计请求数 15秒增量 数据点0 t-1m 1000 - 数据点1 t-45s 1030 +30 数据点2 t-30s 1045 +15 数据点3 t-15s 1060 +15 数据点4 (当前) t 1100 +40 (1)rate(http_requests_total[1m]) 计算
公式:
- rate = (最新值 - 最早值) / 时间窗口(注意:时间窗口指的就是案例中的[1m],时间窗口根据不同的时间而变动,如:[5m]、[10m]等)
计算过程:
- 确定时间窗口内的第一个和最后一个数据点:
- 最早值(t-1m):1000
- 最新值(t):1100
- 计算增量:
- 1100 - 1000 = 100 请求
- 计算时间窗口:
-1分钟 = 60秒- 最终结果:
- 100请求 / 60秒 ≈ 1.67 请求/秒
特点: 反映1分钟内的整体平均请求速率。
(2)irate(http_requests_total[1m]) 计算
公式:
- irate = (最后两个点的差值) / 时间间隔(注意:时间间隔指的就是prometheus.yml文件中的scrape_interval参数定义的采集间隔15秒, 时间间隔根据scrape_interval参数的定义而变动,如:30s、45s等)
计算过程:
- 取最后两个数据点:
- t-15s:1060
- t:1100
- 计算增量:
- 1100 - 1060 = 40 请求
- 计算时间间隔:
- 15秒(固定为采集间隔)
- 最终结果:
- 40请求 / 15秒 ≈ 2.67 请求/秒
**特点:**反映最近15秒的瞬时请求速率。
计算方式 使用数据点 时间范围 结果 适用场景 rate([1m]) 数据点0到数据点4 完整1分钟 1.67 请求/s 长期趋势监控 irate([1m]) 仅数据点3和数据点4 最后15秒 2.67 请求/s 短期突增检测 (3)为什么结果不同:
- **数据点4突发增长:**最后15秒增加了40请求(比其他时段更高)
- rate([]) 平滑了这种突增,irate([]) 放大了这种突增
(4)关键信息:
- **rate([]):**用于稳定的趋势监控(如报表、告警)。
- **irate([]):**用于调试瞬时问题(如故障排查)。
- 黄金法则:
- 生产告警用 rate([]) + 较长窗口(如 [5m])。
- 临时诊断用 irate([]) + 较短窗口(如 [1m])。
生产配置演示:rate([1m])、rate([10m])和irate([1m])、irate([10m])
为了更直观地了解不同窗口时间对触发告警的影响 ,我将使用 rate([1m])、rate([10m])、irate([1m]) 和 irate([10m]) 这四个窗口时间,并配置到生产环境中进行具体测试🔍。因为通过这四个测试,可以直观地看到 窗口时间 对于告警触发的不同影响。并且了解不同的窗口时间对于优化告警机制、避免过度触发或者漏报非常关键⚙️。
特别说明💥: 如下的测试都围绕Linux监控项中的 node_network_transmit_bytes_total 指标展开测试。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter),也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。
rate([1m]):
告警项: HighNetworktransmitUsage(服务器上传带宽使用过高警报)
触发值: rate(node_network_transmit_bytes_total[1m]) * 8 / 1000000 > 500 # 500 Mbps
持续时间: 1m按照如上告警规则,时间窗口是1分钟[1m],rate是基于时间窗口内所有数据点计算的平均增长率,也就是说时间窗口内的平均值达到了触发条件才会触发,也就是说跟时间窗口[1m]有关系,跟采集间隔无关,如果时间窗口内的前几分钟或几秒钟数据很高就会导致平均值高了,导致提前触发。所以如下案例是限流了,触发是在1分钟后,并持续1分钟后发送告警,也就是说发送告警是在2分钟后;如下案例实验得出发送告警是在2分11秒时。
23点10分01秒开始进行scp拷贝:
date
scp -l 512000 mcdb_full_21927_1_20250429 mcdb_full_21918_1_20250426 110.120.100.19:/yl_backup/zhixing_liufei ### 将拷贝的速度限制在 62.5 MB/s,因为如果不限制的话,scp速度会在 100 MB/s左右,速度太快就会导致rate([1m])提前触发告警并发送告警,因为rate = (最新值 - 最早值) / 时间窗口。比如不加以限速,前30秒每秒都是0的话(假设网卡一直没有流量),后30秒每秒使用1000 Mbps的话,30秒就增加了30000 Mbps。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter),也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。那么rate = (30000 - 0 ) / 60 = 500 Mbps,根据时间窗口计算,前30秒虽然都是0,但后30秒每秒都使用了1000 Mbps,所以达到了触发规则的要求,那么首次就会在30秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,而不是时间窗口定的 1 分钟。这里只是为了验证告警的触发时间,所以才进行了scp限制速度。
- scp 使用 -l 参数限制带宽,单位是 Kbit/s(千比特每秒)。换算方式:
- 1 Byte = 8 bits,所以62.5 * 1024 * 8 = 512000
发送告警时间:23点12分12秒触发。 rate = (最新值 - 最早值) / 时间窗口,时间窗口就是1分钟,那么最早值就是1分钟前的值,最新值就是1分钟后的值。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter) ,也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。比如1分钟前的值是0 Mbps,每秒使用500 Mbps的话,那么1分钟后的值就是30000 Mbps,一直递增的状态,那么rate = (30000 - 0 ) / 60 = 500 Mbps,1分钟后触发了告警,持续时间是1分钟,所以发送告警是在2分钟后触发(23点10分01秒 - 23点12分12秒 = 2分11秒)
最后总结一下:按照如上告警规则,时间窗口是1分钟[1m],rate是基于时间窗口内所有数据点计算的平均增长率,也就是说时间窗口内的平均值达到了触发条件才会触发,也就是说跟时间窗口[1m]有关系,跟采集间隔无关,如果时间窗口内的前几分钟或几秒钟数据很高就会导致平均值高了,导致提前触发。所以如上案例是限流了,触发是在1分钟后,并持续1分钟后发送告警,也就是说发送告警是在2分钟后;如上案例实验得出发送告警是在2分11秒时。
rate([10m]):
告警项: HighNetworktransmitUsage(服务器上传带宽使用过高警报)
触发值: rate(node_network_transmit_bytes_total[10m]) * 8 / 1000000 > 500 # 500 Mbps
持续时间: 1m按照如上告警规则,时间窗口是10分钟[10m],rate是基于时间窗口内所有数据点计算的平均增长率,也就是说时间窗口内的平均值达到了触发条件才会触发,也就是说跟时间窗口[10m]有关系,跟采集间隔无关,如果时间窗口内的前几分钟或几秒钟数据很高就会导致平均值高了,导致提前触发。所以如下案例是限流了,触发是在10分钟后,并持续1分钟后发送告警,也就是说发送告警是在11分钟后;如下案例实验得出发送告警是在10分20秒时。
23点30分07秒开始进行scp拷贝:
date
scp -l 512000 mcdb_full_21927_1_20250429 mcdb_full_21918_1_20250426 110.120.100.19:/yl_backup/zhixing_liufei ### 将拷贝的速度限制在 62.5 MB/s,因为如果不限制的话,scp速度会在 100 MB/s左右,速度太快就会导致rate([10m])提前触发告警并发送告警,因为rate = (最新值 - 最早值) / 时间窗口。比如不加以限速,前5分钟每秒都是0的话(假设网卡一直没有流量),后5分钟每秒使用1000 Mbps的话,5分钟就增加了300000 Mbps。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter),也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。那么rate = (300000 - 0 ) / 600 = 500 Mbps,根据时间窗口计算,前5分钟虽然都是0,但后5分钟每秒都使用了1000 Mbps,所以达到了触发规则的要求,那么首次就会在5分钟后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,而不是时间窗口定的 10 分钟。这里只是为了验证告警的触发时间,所以才进行了scp限制速度。
- scp 使用 -l 参数限制带宽,单位是 Kbit/s(千比特每秒)。换算方式:
- 1 Byte = 8 bits,所以62.5 * 1024 * 8 = 512000
发送告警时间:23点40分27秒触发。 rate = (最新值 - 最早值) / 时间窗口,时间窗口就是10分钟,那么最早值就是10分钟前的值,最新值就是10分钟后的值。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter) ,也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。比如10分钟前的值是0 Mbps,每秒使用500 Mbps的话,那么10分钟后的值就是300000 Mbps,一直递增的状态,那么rate = (300000 - 0 ) / 600 = 500 Mbps,10分钟后触发了告警,持续时间是1分钟,所以发送告警是在11分钟后触发(23点30分07秒 - 23点40分27秒 = 10分20秒)
最后总结一下:按照如上告警规则,时间窗口是10分钟[10m],rate是基于时间窗口内所有数据点计算的平均增长率,也就是说时间窗口内的平均值达到了触发条件才会触发,也就是说跟时间窗口[10m]有关系,跟采集间隔无关,如果时间窗口内的前几分钟或几秒钟数据很高就会导致平均值高了,导致提前触发。所以如上案例是限流了,触发是在10分钟后,并持续1分钟后发送告警,也就是说发送告警是在11分钟后;如上案例实验得出发送告警是在10分20秒时。
irate([1m]):
告警项: HighNetworktransmitUsage(服务器上传带宽使用过高警报)
触发值: irate(node_network_transmit_bytes_total[1m]) * 8 / 1000000 > 500 # 500 Mbps
持续时间: 1m
采集间隔: 15s(注意:时间间隔指的就是prometheus.yml文件中的scrape_interval参数定义的采集间隔15秒, 时间间隔根据scrape_interval参数的定义而变动,如:30s、45s等)按照如上告警规则,采集间隔是15s一次,[1m]会采集5个数据点,假设前45秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒都使用很高并达到触发条件,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),irate是基于最后两个数据点计算的瞬时增长率,也就是说跟时间窗口[1m]没关系,跟采集间隔15s有关,并持续1分钟后发送告警,也就是说发送告警是在1分15秒后;如下案例实验得出发送告警是在1分39秒时。
12点30分03秒开始进行scp拷贝:
date
scp -l 512000 mcdb_full_21927_1_20250429 mcdb_full_21918_1_20250426 110.120.100.19:/yl_backup/zhixing_liufei ### irate = (最后两个点的差值) / 时间间隔,因为采集间隔(时间间隔)是15s(prometheus.yml文件中的scrape_interval参数),所以这里的最后两个点的监控数据是第45秒和第60秒。虽然在prometheus中定义采集间隔是15s采集一次,但实际发现每一秒都有数据,并且在同一个采集间隔周期15s中,每一秒的监控数据都一样(如下图)
将拷贝的速度限制在 62.5 MB/s,假设前45秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒使用500 Mbps的话,15秒就增加了7500 Mbps。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter),也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。那么irate = ( 500*15 - 0 ) / 15 = 500 Mbps,根据时间窗口计算,前45秒虽然都是0,但后15秒每秒都使用了500 Mbps,所以达到了触发规则的要求,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,所以可以得出跟时间窗口[1m]没关系,跟采集间隔15s有关。那么根据上面的内容判断,即使使用正常的scp不加以限速,也就是scp速度会在 100 MB/s左右,也不会导致irate([1m])提前触发告警,因为irate = (最后两个点的差值) / 时间间隔,irate只会取最后两个点的监控数据,而不像rate会对整个时间窗口的监控数据进行平均,所以达到首次触发规则也是在第15秒时。
- scp 使用 -l 参数限制带宽,单位是 Kbit/s(千比特每秒)。换算方式:
- 1 Byte = 8 bits,所以62.5 * 1024 * 8 = 512000
发送告警时间:12点31分42秒触发。 irate = (最后两个点的差值) / 时间间隔,时间间隔就是15s(prometheus.yml文件中的scrape_interval参数),所以这里的最后两个点的监控数据是第45秒和第60秒。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter) ,也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。比如1分钟前的值是0 Mbps,每秒使用500 Mbps的话,那么1分钟后的值就是30000 Mbps,一直递增的状态,那么irate = ( 500*15 - 0 ) / 15 = 500 Mbps,根据时间窗口计算,假设前45秒虽然都是0,但后15秒每秒都使用了500 Mbps,所以达到了触发规则的要求,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,所以可以得出跟时间窗口[1m]没关系,跟采集间隔15s有关(12点30分03秒 - 12点31分42秒 = 1分39秒)
最后总结一下:按照如上告警规则,采集间隔是15s一次,[1m]会采集5个数据点,假设前45秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒都使用很高并达到触发条件,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),irate是基于最后两个数据点计算的瞬时增长率,也就是说跟时间窗口[1m]没关系,跟采集间隔15s有关,并持续1分钟后发送告警,也就是说发送告警是在1分15秒后;如上案例实验得出发送告警是在1分39秒时。
irate([10m]):
告警项: HighNetworktransmitUsage(服务器上传带宽使用过高警报)
触发值: irate(node_network_transmit_bytes_total[10m]) * 8 / 1000000 > 500 # 500 Mbps
持续时间: 1m
采集间隔: 15s(注意:时间间隔指的就是prometheus.yml文件中的scrape_interval参数定义的采集间隔15秒, 时间间隔根据scrape_interval参数的定义而变动,如:30s、45s等)按照如上告警规则,采集间隔是15s一次,[10m]会采集41个数据点,假设前585秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒都使用很高并达到触发条件,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),irate是基于最后两个数据点计算的瞬时增长率,也就是说跟时间窗口[10m]没关系,跟采集间隔15s有关,并持续1分钟后发送告警,也就是说发送告警是在1分15秒后;如下案例实验得出发送告警是在1分37秒时。
13点35分05秒开始进行scp拷贝:
date
scp -l 512000 mcdb_full_21927_1_20250429 mcdb_full_21918_1_20250426 110.120.100.19:/yl_backup/zhixing_liufei ### irate = (最后两个点的差值) / 时间间隔,因为采集间隔(时间间隔)是15s(prometheus.yml文件中的scrape_interval参数),所以这里的最后两个点的监控数据是第585秒和第600秒。虽然在prometheus中定义采集间隔是15s采集一次,但实际发现每一秒都有数据,并且在同一个采集间隔周期15s中,每一秒的监控数据都一样(如下图)。
将拷贝的速度限制在 62.5 MB/s,假设前585秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒使用500 Mbps的话,15秒就增加了7500 Mbps。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter),也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。那么irate = ( 500*15 - 0 ) / 15 = 500 Mbps,根据时间窗口计算,前585秒虽然都是0,但后15秒每秒都使用了500 Mbps,所以达到了触发规则的要求,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,所以可以得出跟时间窗口[10m]没关系,跟采集间隔15s有关。那么根据上面的内容判断,即使使用正常的scp不加以限速,也就是scp速度会在 100 MB/s左右,也不会导致irate([1m])提前触发告警,因为irate = (最后两个点的差值) / 时间间隔,irate只会取最后两个点的监控数据,而不像rate会对整个时间窗口的监控数据进行平均,所以达到首次触发规则也是在第15秒时。
- scp 使用 -l 参数限制带宽,单位是 Kbit/s(千比特每秒)。换算方式:
- 1 Byte = 8 bits,所以62.5 * 1024 * 8 = 512000
发送告警时间:13点36分42秒触发。 irate = (最后两个点的差值) / 时间间隔,时间间隔就是15s(prometheus.yml文件中的scrape_interval参数),所以这里的最后两个点的监控数据是第45秒和第60秒。在prometheus中node_network_transmit_bytes_total 是一直递增的计数器(Counter) ,也就是说会记录从系统启动开始,网卡发送的 累计字节数 ,数值会越来越大,除非网卡重启或Prometheus客户端重启,计数器可能归零(但rate()会自动处理这种重置)。比如1分钟前的值是0 Mbps,每秒使用500 Mbps的话,那么1分钟后的值就是30000 Mbps,一直递增的状态,那么irate = ( 500*15 - 0 ) / 15 = 500 Mbps,根据时间窗口计算,假设前585秒虽然都是0,但后15秒每秒都使用了500 Mbps,所以达到了触发规则的要求,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),并持续1分钟后发送告警,所以可以得出跟时间窗口[10m]没关系,跟采集间隔15s有关(13点35分05秒 - 12点36分42秒 = 1分37秒)
最后总结一下:按照如上告警规则,采集间隔是15s一次,[10m]会采集41个数据点,假设前585秒每秒都是0的话(假设网卡一直没有流量),后15秒每秒都使用很高并达到触发条件,那么首次就会在15秒后触发告警(这里的首次指定就是在添加完成告警规则后立马很多的数据立刻进来),irate是基于最后两个数据点计算的瞬时增长率,也就是说跟时间窗口[10m]没关系,跟采集间隔15s有关,并持续1分钟后发送告警,也就是说发送告警是在1分15秒后;如上案例实验得出发送告警是在1分37秒时。
呼,结束了🎉!到现在已经是1.5万字+了,为了弄清这两个函数博主可是费了3天的时间认真钻研。我相信通过上面的四个测试,大家直观地看到 窗口时间 对于告警触发的不同影响。因此了解不同的窗口时间对于优化告警机制、避免过度触发或者漏报非常关键⚙️。
因此关于rate() 和 irate() 函数记住如下核心要点💡:
rate() = 结果平滑,适合长期趋势分析(稳)
irate() = 对短期波动敏感,适合捕捉突增(快)
如果觉得这篇硬核教程有帮助:
👍 点赞让更多小伙伴看到
⭐️ 收藏备查不迷路
💬 评论区交流你的使用心得