深入理解Prometheus: rate irate increase
liebian365 2024-11-14 18:05 31 浏览 0 评论
在上一篇《深入理解Prometheus: metric type》已经介绍了Counter类型,其值只会上升,它表示累积的总计数,例如“我们总共处理了多少请求?”或“我们花了多少秒处理请求?”。由于计数器的值取决于跟踪和公开它的进程的初始(重新)启动时间,因此计数器的绝对值几乎没有用处。因此,在用计数器绘制图形或做任何其他事情之前,您通常希望将其包装在类似rate(),的函数中irate(),或者increase()查看计数器上升的速度。这三个函数的确切行为经常引起混淆,因此在这篇文章中,我们将详细介绍它们中的每一个,以及它们如何处理计数器重置并进行数据推理获得最终值。
概述
以下是计算计数器增长率的三个函数之间差异的概述:
- rate():计算每秒的增长率,在整个提供的时间窗口内平均。示例:rate(http_requests_total[5m])在 5 分钟的时间窗口内产生每秒 HTTP 请求的平均速率。这个函数是最常见的,因为它产生了一个很好的平滑速率和一个可预测的每秒输出单位。
- irate()("instant rate"):计算每秒的增长率,就像计算一样rate(),但只考虑在提供的时间窗口下的最后两个样本进行计算,并忽略所有较早的样本。示例:irate(http_requests_total[5m])查看提供的 5 分钟窗口下的最后两个样本,并计算它们之间的每秒增长率。如果您想使放大的图表显示对速率变化的快速响应,此功能会很有帮助,但输出会比 for 更加尖锐。
- increase(): 这个函数完全等同于,rate()除了它不将最终单位转换为“每秒”( 1/s)。相反,最终的输出单元是每个提供的时间窗口。示例:increase(http_requests_total[5m])产生在 5 分钟窗口内处理的 HTTP 请求的总增加量(单位:1 / 5m)。因此increase(foo[5m]) / (5 * 60)100% 等价于rate(foo[5m])。
所有三个函数都要求在提供的范围窗口下至少需要两个样本才能工作。窗口下少于两个样本的系列会简单地从结果中删除。在给定固定时间窗口和落在该窗口下的一些数据点的情况下,如何准确计算增加是一个权衡和不完美近似的问题。Prometheus 选择的方法旨在平均提供最正确的答案,仅考虑提供的窗口下的有限数据。让我们更详细地看看它是如何做到的:
数据推算(拟合)
经常让人们感到困惑的是rate()和increase()函数的推算行为。例如,即使对于只有整数增量的计数器,increase()也可以返回非整数结果2.5883。原因是它试图在指定时间窗口的总持续时间(例如 5 分钟)内尝试近似计数器的增加。但实际上,在时间窗口下找到的第一个和最后一个样本永远不会 100% 与提供的时间窗口的开始和结束重合。因此increase(foo[5m]) 将窗口下的第一个和最后一个数据点之间的斜率延伸到窗口边界,以得出一个平均接近整个窗口的预期增加的值(实际上在窗口边界处确实有样本)。
下图显示了一个使用rate() 1 分钟窗口和间隔 15 秒的样本的示例,在窗口下方发生了一个实际计数器增加1:
如图所示,结果基于窗口下第一个和最后一个样本之间的斜率并推测到窗口边界。
注意:这种行为有一些例外:当一个系列看起来像是在提供的时间窗口内开始或结束时,我们不希望在系列终止的方向上推测太远。rate()和increase()预测第一个或最后一个样本距离其各自窗口边界的距离超过窗口下样本之间的平均间隔的 1.1 倍时停止。在这种情况下,推测仅向窗口边界延伸平均采样间隔的一半,而不是一直延伸。类似地,这些函数避免推测到负值,因为计数器总是从0并且永远不会是负面的。
由于irate()实际上只查看两个样本之间的每秒增加量,因此它不会进行任何这种推测。
计数器重置
尽管计数器通常只会上升,但它们会0在跟踪它们的进程重新启动时重置。为了不将这些重置解释为实际的负利率,与计数器相关的函数具有检测和处理这些重置的逻辑:在提供的时间窗口下迭代样本时,函数检查是否有任何样本的值低于前一个,并将这种情况解释为计数器重置。使用计数器总是在复位后开始的进一步假设0,这些函数然后只是将新的样本值添加到先前看到的样本值,以补偿复位。
以下示例图显示了rate()计算如何处理在提供的窗口下发生的计数器重置。您可以将其想象为rate()从底层的“真实”样本创建一组“虚拟”样本。然后根据虚拟样本计算最终速率,就好像从未发生过重置一样:
注意:每当计数器重置时,它有可能在Prometheus 上次抓取之后但在重置之前递增。Prometheus 永远失去了这些增量,并且无法将它们取回。为了最大限度地减少这种影响,重置应该只偶尔发生一次,并且比 Prometheus 抓取目标的频率要低得多。
rate vs irate
rate() Source code
//promql/functions.go
// FunctionCalls is a list of all functions supported by PromQL, including their types.
var FunctionCalls = map[string]FunctionCall{
......
"rate": funcRate,
}
// === rate(node parser.ValueTypeMatrix) Vector ===
func funcRate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return extrapolatedRate(vals, args, enh, true, true)
}
func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper, isCounter bool, isRate bool) Vector {
ms := args[0].(*parser.MatrixSelector)
var (
samples = vals[0].(Matrix)[0]
lastValue float64
)
for _, sample := range samples.Points {
......
lastValue = sample.V
}
resultValue := lastValue - samples.Points[0].V
if isRate {
resultValue = resultValue / ms.Range.Seconds()
}
......
}
irate() Source code
//promql/functions.go
// FunctionCalls is a list of all functions supported by PromQL, including their types.
var FunctionCalls = map[string]FunctionCall{
......
"irate": funcIrate,
}
// === irate(node parser.ValueTypeMatrix) Vector ===
func funcIrate(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector {
return instantValue(vals, enh.out, true)
}
func instantValue(vals []parser.Value, out Vector, isRate bool) Vector {
samples := vals[0].(Matrix)[0]
lastSample := samples.Points[len(samples.Points)-1] // The last point
previousSample := samples.Points[len(samples.Points)-2] // The previous point
var resultValue float64
if isRate && lastSample.V < previousSample.V {
// Counter reset.
resultValue = lastSample.V
} else {
resultValue = lastSample.V - previousSample.V
}
sampledInterval := lastSample.T - previousSample.T
if isRate {
// Convert to per-second.
resultValue /= float64(sampledInterval) / 1000
}
}
irate should only be used when graphing volatile, fast-moving counters. Use rate for alerts and slow-moving counters.
rate should only be used with counters. It is best suited for alerting, and for graphing of slow-moving counters.
- rate Calculate... Within a specified time range : The incremental / Time range ;
- irate Calculate... Within a specified time range : The increment of the last two points / The time difference between the last two points ;
- irate Suitable for calculating rapidly changing counter, It can reflect counter Rapid changes in ;
- rate Suitable for calculating slowly changing counter, It flattens the peak with an average ( Long tail effect );
Obviously, the difference between rate() and irate() basically vanish when the range interval gets sufficiently small. If your range interval for rate() only includes two metric points, it's just the same as irate(). However, it's easier to make irate() reliable at small range intervals; if you use rate(), it may be chancy to insure that your range interval always has two and only two points. irate() automatically arranges that for you by how it works.
Often when we use either rate() or irate(), we want to graph the result. Graphing means moving through time with query steps and that means we get into interactions between the query step and both the range interval and the function you're using.
In particular, as the query step grows large enough, irate() will miss increasingly large amounts of changes. This is because it is the instant rate of change at the end of your range interval (using the two last metric points). When the query steps include more than two points in each interval, you lose the information from those extra points. As an extreme example, imagine a query step of five minutes and a metric that updates every thirty seconds. If you use irate(), you're only seeing the last minute out of every five minute slice of time; you have no idea of what happened in the other four minutes, including if there was an activity spike in them. If you use rate() instead, you can at least have some visibility into the total changes across those five minutes even if you don't capture any short term activity spikes.
相关推荐
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
-
明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
-
齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...
- Qt界面——搭配QCustomPlot(qt platform)
-
这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
-
老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
-
用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
-
前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...
- 掌握Visual Studio项目配置【基础篇】
-
1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
-
随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...
- Visual Studio Community 2022(VS2022)安装图文方法
-
直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...
- Qt添加MSVC构建套件的方法(qt添加c++11)
-
前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...
- Qt为什么站稳c++GUI的top1(qt c)
-
为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...
- qt开发IDE应该选择VS还是qt creator
-
如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...
- Qt 5.14.2超详细安装教程,不会来打我
-
Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...
- Cygwin配置与使用(四)——VI字体和颜色的配置
-
简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)