rate() 和 increase() 为什么会给出小数?窗口取多长?irate 和 rate 怎么选?进程重启时 counter 的哪些增量会丢?这篇用 Prometheus 3.15.0 和增长速度已知的 counter 逐项量出来。
counter | 60 s 窗口里的真实增量 | 得到结果的时刻数 | increase 最小 | increase 最大 | increase 平均 ---------+---------------+----------+-------------+-------------+------------ c_steady | 600 | 17 | 599.97 | 600.03 | 600.00 c_sparse | 3 | 17 | 2.18 | 3.27 | 2.95 increase() 用窗口内第一个和最后一个样本之间的增量,按窗口边界与样本的距离做线性外推;外推之后整数 counter 也会得到小数,单个窗口的结果会偏离真实值,取平均更接近真实值
increase 对窗口边界外推,整数 counter 会得到小数,稀疏事件偏差更大。
窗口 W | 窗口内的样本数 | rate(c_steady[W]) -----+---------+------------------ 5 s | 1 | (没有结果) 10 s | 2 | 10.00 15 s | 3 | 10.00 20 s | 4 | 10.00 30 s | 6 | 10.00 rate() / increase() 至少要窗口里有两个样本才能算;窗口恰好等于抓取间隔时可能只有一个样本,返回空;窗口里只有两三个样本时结果受外推和抓取时刻的影响很大,所以窗口至少要取抓取间隔的几倍
窗口里至少要有两个样本才能算,窗口要取抓取间隔的几倍。
函数 | 最小(/s) | 最大(/s) | 标准差 | 取值的时刻数 --------------------+--------+--------+-------+------- irate(c_burst[30s]) | 0.0 | 400.0 | 169.7 | 17 rate(c_burst[30s]) | 80.0 | 160.0 | 33.9 | 17 整个周期(20 s)里平均每秒 +100。irate 反映抓取到的最近两点之间的瞬时速度,变化剧烈,适合看当前的尖峰;rate 对整个窗口平均,更平滑,适合告警和长期趋势
irate 看最近两个样本的瞬时速度,rate 对整个窗口平均。
两个进程实际增加的总量 3600(崩溃前 1200 + 重启后 2400);Prometheus 抓到的第一个样本是 0;崩溃前最后一次成功抓到的值是 1000,崩溃时是 1200,这 200 的增量永远没有被抓到。所以 increase 能反映的上限是 实际总量 − 第一个样本的值 − 没被抓到的增量 = 3600 − 0 − 200 = 3400 increase(c[2m]) = 3448,与上限 3400 的差是 +48(increase 会对窗口两端做外推,这个差我没有逐项拆解);崩溃前后没被抓到的那 200 个增量无法从 Prometheus 里找回 样本序列(时间相对第 0 s,值):4s:400 6s:600 8s:800 10s:1000 18s:200 20s:400 22s:600 24s:800 26s:1000 28s:1200 30s:1400 32s:1600 34s:1800 36s:2000 38s:2200 40s:2400
崩溃前后没被抓到的增量无法找回。
抓到的样本:-0.1s:200 +1.9s:300 +3.9s:300;重启前最后抓到 200,重启后新进程实际增加 300(0 → 300);Prometheus 看到 200 → 300,没有出现“值变小”,resets() = 0.0。窗口里 200 → 300 这一段的增量是 100,真实新增是 300,少算了 200
ERRORS {}重启后马上增长到比崩溃前还大的值,Prometheus 看不出是重启。