背景

当前在Grafana图表和告警规则中,在计算增长率场景上使用着不同的函数比如rate、irate、increase、offset等,为了降低图表和告警的配置成本以及维护成本,本文意图研究当前常用函数的用法,归纳总结出一些通用易于理解、编写的函数用法。

常用函数介绍

通过计算结果简单对比

以下是各个函数的计算效果的简单对比表格

函数适用类型平滑平均到秒推算(Extrapolated)
rateCounterYYY
irateCounterNYY
increaseCounterYNY
offsetAnyYNN
deltaGaugeYNY
ideltaGaugeNNY
平滑:根据计算窗口大小可以产生平滑效果,而不是实际变化值
推算(Extrapolated):如果实际采集间隔与配置采集间隔有差异,会换算成配置采集间隔对应的值,因此可能产生小数。

函数简介

函数适用类型作用计算原理是否兼容CounterReset特殊说明链接
rateCounter计算向量在每个时间范围内的每秒平均增长率采用时间范围内的第一个值与最后一个值进行差值运算再除以两值之间的时间差Y与聚合函数一起使用时不兼容CounterReset官方链接
irateCounter计算向量在每个时间范围内的每秒瞬时增长率采用时间范围内的最后两个值进行差值运算再除以两值之间的时间差Y与聚合函数一起使用时不兼容CounterReset官方链接
increaseCounter计算向量在每个时间范围内的增量通过rate的计算原理计算后乘以时间间隔范围Y与聚合函数一起使用时不兼容CounterReset官方链接
offsetAny更改查询中的向量的时间偏移从而获取时间偏移后的值通过当前值的时间减去偏移值得到编译后的时间再获取相应的值Noffset是一个修饰符,两个周期之间的数据点数不对称时进行运算,会丢弃这部分数据出现空数据官方链接
deltaGauge计算向量在每个时间范围内的第一个值与最后一个值的差值采用时间范围内的第一个值与最后一个值进行差值运算N官方链接
ideltaGauge计算向量在每个时间范围内的最后两个值的差值采用时间范围内最后两个值进行差值运算N官方链接

函数使用对比

irate 与 rate的对比

我们将通过模拟一个采集频率为1分钟的指标的数据,对irate与rate做两个场景的数据比对

  • 一个是 [3m],观察当时间范围内有3个值时两者的差异
  • 另一个是[2m],观察当时间范围内两者均只有2个值的差异假设指标为

http_server_requests_seconds_count,该指标采集间隔为1分钟

假定采集10分钟的数据如下
图片

当时间范围为[3m]时irate运算式为irate(http_server_requests_seconds_count[3m])rate运算式为 rate(http_server_requests_seconds_count[3m])计算结果如下
图片

当时间范围为[2m](采集间隔 * 2)时irate运算式为irate(http_server_requests_seconds_count[2m])rate运算式为 rate(http_server_requests_seconds_count[2m])计算结果如下
图片

由上述数据图表可见,
在[3m]的场景下使用rate的曲线相对于 irate时要平缓的许多,这就导致用户无法感知到细微的变化从而对当前运行情况误判的可能性较高,而irate的效果就很符合用户的观察细微变化需求。
在[2m]既采集间隔的2倍场景下,两者的曲线是一致的,也就是效果是一致的。
irate在【3m】、【2m】的场景数据下计算结果是一样的,这结果是符合irate的计算原理的预期,但如果【3m】 场景中某分钟的数据没有采集到时,也因为计算原理的原因,会向前获取数据进行计算进行补点,导致空数据的情况无法表现出来,这是不太能接受的情况。
所以当前符合业务预期的使用方式,应是采用 irate[采集间隔2] 或者 rate[采集间隔2] 对数据进行计算,
在grafana图表使用上也不应该继续使用rate[$__rate_interval], $__rate_interval会随着图表的选择的时间进行相应的变化,这会触发rate的平滑效果,从而导致数据图表数据显示不符合用户预期。

如果遇到采集间隔小于1m的情况下,
告警评估频率因性能问题不建议低于1m,此时告警语句只能使用rate[1m]或irate[1m]进行评估,
图表采用上述 irate[采集间隔2] 或者 rate[采集间隔2] 时,推荐直接使用 irate[1m] 。理由如下

  • 采用rate[1m]时,通过1分钟中的第一个点与最后一个点的数据进行计算,这样造成中间数据被忽略,造成平滑效果,无法在图表中观察,用户会对告警产生质疑。
  • 采用 irate[1m] 时,通过1分钟中最后两个点进行计算,产生的计算结果包含在 irate[采集间隔2] 或者 rate[采集间隔2]的计算结果中,因此在图表上也能观察到该数据,降低用户质疑。

rate 与 offset 与increase

我们经常在计算一个较大的时间范围内的增量的场景常使用rate、offset和increase 。

在使用offest时,我们经常需要编写类似这样的运算式 http_server_requests_seconds_count{api="x"} - http_server_requests_seconds_count{api="x"} offset 1m,虽然它能实现我们想要的结果,但是要嵌套进更复杂的语句时,可阅读性会变得更差、语句逻辑也更加容易出错。

因此本文探索出一种可以与offset的计算结果一致,也容易理解并编写的rate用法,既rate[时间范围+采集间隔] * 时间范围,这里的时间范围是原offset指定的时间范围
比如 利用 rate与irate的对比一节中假设的http_server_requests_seconds_count数据进行运算比对

  • offset运算式为http_server_requests_seconds_count{} - http_server_requests_seconds_count{} offset 1
  • rate运算式为 rate(http_server_requests_seconds_count{}[2m]) * 1m计算结果如下

图片

因此通过rate[时间范围+采集间隔] * 时间范围可以平替offset的使用,在写法上也简洁易懂,唯一的不足是需要知道数据的采集间隔,但当前业务使用上采集间隔为1分钟的占据绝大部分,所以该用法可以采纳使用。

为什么不推荐increase?

实际运用时发现increase因实现算法问题,计算结果与offset预想差距大比如采集频率为一分钟,采集5次的数据为 [ 0 1 2 3 4 ],使用increase[2m]计算,第3分钟的计算式为  (2-1)/1m  2m,实际上更加符合预期的应该是 (2-1)/1m  1m,这导致数据一直会有偏差,而且这个偏差是随着 时间间隔范围 变大而变大,故不推荐使用。

结论    

经过上述章节描述,遵循图表与告警的语句需相同的原则,建议如下

  1. 当前绝大部份项目使用1分钟采集间隔情况下,图表与告警统一采纳使用rate进行函数计算,因其泛用性更强,可以使用以下用法覆盖大部分当前场景利用 rate[采集间隔*2]  的用法,有以下效果

    • 可实现irate的高灵敏度的效果,能支持空数据的展示
    • 在当前均使用offest 1m的背景下,可以平替offset的使用,语句简单、直接使编写以及阅读 更人性化,且支持counter reset的场景
  2. 对于平台使用5s的特殊场景,图表采用与绝大部份项目使用1分钟采集间隔的用法,而告警采用以下用法

    • 利用 irate[1m]  的用法,进行数据告警,可以观察到1分钟内的最后2个点的数据变化,在图表上也能观察到该数据,用户会更信任该告警有效性。
    • 利用 rate[时间范围+采集间隔] * 时间范围 的用法,此时的时间范围>=1分钟,可以平替offset的使用,使语句简单、直接使编写以及阅读更人性化,且支持counter reset的场景。

参考文档


EdwardQ
36 声望14 粉丝

低调的运维研发Golang 工程师