多维度优化降低Prometheus资源消耗的实践
2025-03-28 tech prometheus 4 mins 1664 字
最近在玩 Prometheus ,我在grafana上使用了以下PromQL查询:
sum by (user) (
rate(iftop_traffic_bytes_total{direction="send",user!=""}[1m])
) > 1000
这个查询导致 Prometheus 主机系统负载高的问题。通过count by (__name__)({__name__=~".+"})
分析发现,iftop_traffic_bytes_total
指标存在约5万个时间序列,其中user
标签的基数占比超过75%。
一、分阶段优化过程
阶段一:查询层优化
1. 过滤无效标签
user!~"(?:^$|default|system)"
该操作减少约8%的时间序列数量,但查询延迟仅从3.2s降至3.0s,效果有限。
2. 调整时间窗口
将计算窗口从[1m]
缩短至[30s]
:
原始执行时间:3.2s → 2.7s
但观察到流量曲线有些波动,pass。
阶段二:数据源治理
3. 指标生成层过滤
通过改造指标生成脚本,在数据源头排除无效数据:
# 原始数据采集脚本片段
awk '/iftop_traffic_bytes_total/ && $6 != "" {print $0}' raw_metrics.log > metrics.prom
优化效果:
- 指标生成量减少12%
user
标签基数从5200下降至4600- Prometheus TSDB写入速率降低15%
4. 采集配置增强
在prometheus.yml
中补充过滤规则:
metric_relabel_configs:
- source_labels: [user]
regex: '^(?:|default|system)$'
action: drop
双重保障确保无效数据不会进入存储环节。
阶段三:计算层优化
5. 预计算规则
配置Recording Rules实现查询逻辑固化:
- record: job:iftop_traffic_bytes:rate1m
expr: |
rate(iftop_traffic_bytes_total{
direction="send"
}[1m])
优化后的查询语句简化为:
sum by (user) (job:iftop_traffic_bytes:rate1m) > 1000
二、效果验证
通过多维度优化措施组合实施,系统指标变化如下:
优化阶段 | 时间序列数量 | 查询延迟 | 内存消耗 |
---|---|---|---|
原始状态 | 52,000 | 3200ms | 1.2GB |
查询层优化后 | 47,800 | 2700ms | 900MB |
数据源治理后 | 42,000 | 2200ms | 750MB |
预计算规则启用后 | 820 | 420ms | 150MB |
通过rate(prometheus_engine_query_duration_seconds_sum[1h])
指标观测,查询延迟P99值下降89%。
三、衍生效益
基于优化后的数据模型,我扩展实现了以下监控指标:
# 实时在线用户数
count(sum by (user)(job:iftop_traffic_bytes:rate1m) > bool 1)
四、经验总结
- 源头治理优先:在指标生成环节过滤无效数据,比后期处理更高效
- 分层防御体系:结合脚本过滤+metric_relabel_configs构建双重保障
- 预计算价值:Recording Rules将复杂查询转换为简单检索,效果显著
- 基数监控:建立
count(count by (user)({__name__=~".+"}))
例行检查机制