关于prometheus:prometheus-rate与irate分析与源码

论断

rate与irate都能够计算counter的变化率。
区别:

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

场景:

  • irate适宜计算疾速变动的counter,它能够反映出counter的疾速变动;
  • rate适宜计算迟缓变动的counter,它用平均值将峰值削平了(长尾效应);

rate()函数详解

计算demo_api_request_duration_seconds_count最近1min的每秒变化率:

rate(demo_api_request_duration_seconds_count[1m])

计算方法:

  • 取工夫范畴内的firstValue和lastValue;
  • 变化率 = (lastValue – firstValue) / Range;

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

  • 对每个数据点,计算(value – valueBeforeRange)/range;
  • 最终失去一串数据,绘制变化率图形;

当抓取指标的过程重启时,counter可能会重置为0,rate()认为指标值只有缩小了就认为被重置了,而后它会主动进行调整。

rate()源码剖析

//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()函数详解

应用rate计算疾速变动的样本均匀增长率时,容易陷入长尾问题,因为它用平均值将峰值削平了,无奈反映工夫窗口内样本数据的疾速变动。
与rate相似,irate同样能够计算counter的均匀增长率,但其反映出的是刹时增长率
irate计算增长率时,应用指定工夫范畴内的最初两个样本数据:

//官网doc的形容
irate(v range-vector) calculates the per-second instant rate of increase of the time series in the range vector. 
This is based on the last two data points. 
Breaks in monotonicity (such as counter resets due to target restarts) are automatically adjusted for.

因为rate()提供更平滑的后果,因而在长期趋势剖析或告警中更举荐rate(),当迅速产生一个短暂的峰值,不应该触发告警。

irate()源码剖析

//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]        //最初一个点
    previousSample := samples.Points[len(samples.Points)-2]    //前一个点

    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
    }
}

参考:

1.https://prometheus.io/docs/pr…
2.https://prometheus.io/docs/pr…
3.https://mp.weixin.qq.com/s/7z…

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理