Prometheus Pushgateway重启后Count/Sum指标正确求和方法咨询
这确实是Pushgateway的经典痛点——它本质是内存级存储,一重启所有临时指标直接清空,普通的sum或者rate根本搞不定这种需要持久化累加的场景。我之前做前端用户行为统计时踩过一模一样的坑,给你分享几个亲测有效的方案:
1. 先修正指标类型与推送逻辑(最基础的解决方法)
别用counter类型推送到Pushgateway!counter会因为Pushgateway重启重置,而且前端刷新后自身的counter也会清零。正确的姿势是:
- 前端用localStorage持久化累计次数:每次打开对话框时,先从localStorage读当前累计值,加1后更新存储,再把这个最新的累计值以
gauge类型推送到Pushgateway。比如指标名设为dialog_open_total,带上user_id、dialog_type这类标签。 - 推送命令示例:
这样哪怕Pushgateway重启,前端下次推送时会把最新的累计值传上去,不会出现数据断档。echo "dialog_open_total{user_id='user_123',dialog_type='profile_settings'} 8" | curl --data-binary @- http://pushgateway:9091/metrics/job/frontend_dialog_tracking
2. 正确使用sum_over_time分组查询(解决你之前的报错问题)
你之前加by子句报错,大概率是语法顺序错了!正确的逻辑是先计算每个时间序列的增量,再分组求和,而不是把by嵌在sum_over_time里。举几个常用的查询:
- 统计过去1天内各类型对话框的总打开次数:
这里sum(increase(dialog_open_total[1d])) by (dialog_type)increase()会自动计算每个序列在时间范围内的增量,再用sum by按类型聚合。 - 统计从指标存在至今的总次数(适合长期统计):
sum(last_over_time(dialog_open_total[1d])) - sum(min_over_time(dialog_open_total[1d]))last_over_time取每个序列的最新累计值,min_over_time取初始值(如果前端初始是0,那min就是0),相减就是真实的总次数。
3. 用Prometheus记录规则做数据快照(兜底方案)
如果担心Pushgateway意外重启导致短时间内数据缺失,可以在Prometheus里配置记录规则,定期把Pushgateway的指标快照保存到Prometheus自己的TSDB中(TSDB是持久化的)。示例规则:
groups: - name: dialog_metrics_snapshot rules: - record: dialog_open_total:snapshot expr: dialog_open_total labels: source: prometheus_snapshot interval: 1m
之后查询时就可以基于这个快照指标,比如统计过去7天的总次数:
sum(increase(dialog_open_total:snapshot[7d])) by (dialog_type)
4. 终极方案:放弃Pushgateway,直接用Remote Write上报
如果你的场景对数据完整性要求极高,Pushgateway的内存存储本质就不适合。可以用前端直接通过Remote Write协议上报指标到支持持久化的存储(比如Prometheus本身、Thanos、M3DB等)。比如用prom-client库的Remote Write功能,指标直接落地到TSDB,重启完全不影响,查询起来也更可靠。
为什么你之前的sum不符合预期?
因为sum只能统计当前Pushgateway中存在的指标序列,一旦Pushgateway重启,之前的序列消失,sum就会漏掉那些用户的历史数据,结果自然不对。
内容的提问来源于stack exchange,提问作者Tim Schwalbe

