Prometheus性能问题根源在于高基数标签引发的连锁反应:标签组合爆炸导致时间序列激增,进而加剧存储压力、拖慢查询、阻塞规则评估。需通过count by语句定位超10万序列的指标,用relabel_configs删除trace_id等高基数标签,调大scrape_interval降写入压力,并结合prometheus_tsdb_head_series等内部指标实时监控。

Prometheus 性能问题通常不是突然出现的,而是随着指标数量、标签维度和查询复杂度缓慢积累的结果。真正影响稳定性的,往往不是单个配置项,而是多个环节叠加后的连锁反应——比如高基数标签放大了存储压力,又拖慢了查询响应,进而让规则评估排队,最终导致告警延迟甚至丢失。
识别高基数指标与标签
高基数(High Cardinality)是 Prometheus 最常见的性能根源。一个带 10 万个唯一 path 值的 http_requests_total 指标,会生成 10 万条独立时间序列,直接撑爆内存和索引。关键是要快速定位这类“罪魁祸首”:
- 查标签组合数:用 count by (__name__, job) ({__name__=~".+"}) 查各指标的序列数量,重点关注超 10 万的
- 查具体标签值分布:如 count by (path) (http_requests_total) 看 path 标签是否失控
- 检查内部指标:prometheus_tsdb_head_series 持续高于 50 万,基本可判定存在高基数问题
优化抓取配置与标签处理
很多资源浪费发生在数据进入 TSDB 之前。不加筛选地拉取、保留无用标签,等于主动制造垃圾。
- 调大 scrape_interval:非核心服务从 15s 改为 30s 或 60s,写入压力可降 50% 以上
- 用 relabel_configs 删除冗余标签:比如移除 trace_id、request_id 这类每次请求都不同的标签
- 用 metric_relabel_configs 丢弃低价值指标:如以 _total 结尾但无聚合意义的中间计数器
- 限制单次抓取目标数:通过 max_concurrent 控制并发,避免瞬时拉取风暴
调整存储与查询行为
TSDB 不是黑盒,它的块结构、压缩逻辑和查询路径都直接影响响应速度。
- 缩短 storage.tsdb.retention.time:从默认 15d 缩到 7d,可显著降低内存驻留序列数和磁盘占用
- 监控 prometheus_tsdb_head_chunks 和 prometheus_tsdb_compaction_duration_seconds:若 compaction 频繁失败或耗时过长,说明块合并压力大,需减少写入量或升级磁盘 I/O
- 避免大范围查询:Grafana 中 range query 时间跨度别超过 24h;用 rate() 替代 increase() 减少数据点扫描量
- 聚合后再查:对高频指标(如容器 CPU),优先在 recording rule 中预计算 sum by (pod) (rate(container_cpu_usage_seconds_total[5m])),查面板时直接用聚合结果
利用内部指标做自监控
Prometheus 自己暴露的指标,就是最真实的健康报告。它们比外部 ping 更早发现异常。
- prometheus_rule_evaluation_duration_seconds 的 P99 超过 2s?说明规则引擎已吃紧,要检查是否有未加 rate() 的 count() 类查询
- prometheus_target_scrapes_exceeded_sample_limit_total > 0?表示某些 target 返回样本超限(默认 5 万),需在 exporter 端限流或过滤
- prometheus_remote_storage_pending_samples 持续 > 1000?远程写队列积压,可能是网络或后端存储瓶颈
- 结合 process_resident_memory_bytes 和 go_memstats_heap_alloc_bytes,判断内存增长是真实负载上升,还是 GC 异常或泄漏


















