如何正确计算Prometheus Gauge指标24小时的数值变化?
问题背景
我维护着一个Prometheus Gauge指标not_processed_records_total,用于追踪未处理记录的数量。这个指标由多个生命周期约1小时的Worker采集:每个Worker启动时从数据库拉取当前未处理记录总数,之后每处理一条记录就递减该Gauge值。
在Grafana中,用avg(not_processed_records_total)在时间序列组件展示指标趋势效果正常,但需要在Stat组件中展示24小时内的总处理记录数(即24小时前的未处理数与当前未处理数的差值)。例如当前未处理数约607000,24小时前约684000,预期结果为77000。
最初尝试的查询语句:
avg(-delta(not_processed_records_total[24h]))
得到的结果却仅约3000,更接近单小时的处理量,与预期不符。
问题分析
delta()函数的作用是计算单条时间序列在指定时间范围内的数值差值。由于Worker的生命周期只有1小时,24小时内大部分旧Worker实例已经终止,delta()只会对当前仍在运行的(不足1小时的)Worker计算变化量。再用avg()聚合时,得到的只是单Worker的平均处理量,而非全局所有Worker的总处理量。
解决方法
改用sum()聚合所有Worker的delta()结果,将每个Worker的处理量(-delta()取负后的值)累加,得到全局24小时总处理记录数:
sum(-delta(not_processed_records_total[24h]))
该查询会统计24小时内所有存在过的Worker的处理量总和,结果与预期一致。
补充说明
虽然明确知道这里用Gauge不是最优方案(应使用Counter直接统计处理量),但在现有Gauge架构下,sum()+delta()的组合可以满足需求。另外,未聚合的单Worker数据显示avg/min/max结果相近,说明各Worker启动时的未处理数同步性良好,不会影响最终聚合结果。
内容的提问来源于stack exchange,提问作者Roman Klimenko

