Prometheus 常见陷阱与最佳实践
本文档汇总 Prometheus 使用中的常见陷阱、最佳实践清单和性能优化建议。
符号说明
| 符号 | 含义 |
|---|---|
| 🚨 | 陷阱 / Pitfall |
| 💡 | 最佳实践 / Best practice |
| 🔬 | 深入原理 / Deep-dive |
| ⚡ | 性能提示 / Performance note |
1. 🚨 十大常见陷阱
| # | 陷阱 | 说明 | 解决方案 |
|---|---|---|---|
| 1 | 先 sum 再 rate | rate(sum(counter)) 破坏了 Counter 重置检测 |
始终 sum(rate(counter[...])) |
| 2 | 标签基数爆炸 | user_id、request_id 作为标签导致 TSDB 膨胀 |
只使用有界标签(HTTP 方法、状态码等) |
| 3 | rate() 窗口太短 |
rate(counter[1m]) 在 scrape_interval=60s 时只有 1 个样本点 |
窗口 ≥ 4× scrape_interval |
| 4 | 告警不加 for |
短暂毛刺立即触发告警 | 加 for: 5m 防抖动 |
| 5 | histogram_quantile() 忘记 by (le) |
返回 NaN | 聚合时始终保留 le 标签 |
| 6 | Summary 跨实例聚合 | 50 台的 P99 平均值 ≠ 全局 P99 | 跨实例聚合用 Histogram |
| 7 | Gauge 当 Counter 用 | 对内存使用率用 rate() |
Gauge 直接查询或用 avg_over_time() |
| 8 | Pushgateway 指标未清理 | 旧任务指标残留,误导告警和看板 | 任务结束后 DELETE 自己的指标 |
| 9 | 忽略外部标签 | 多集群环境下同名指标混淆 | 设置 global.external_labels |
| 10 | 不限制 sample_limit | 一个 rogue 目标暴露百万条指标拖垮 Prometheus | 每个 job 设置 sample_limit |
2. 💡 最佳实践清单
| 类别 | 实践 | 说明 |
|---|---|---|
| 指标设计 | Counter 以 _total 结尾 |
社区约定,一眼能识别指标类型 |
| 指标设计 | 时间单位统一用秒 | _seconds,不要混用毫秒 |
| 指标设计 | 标签基数有界 | 不要用 email、user_id、trace_id 作为标签 |
| 指标设计 | 初始化标签组合 | counter.WithLabelValues("x").Inc(0) 让指标从 0 开始 |
| PromQL | 先 rate 后 sum | sum(rate(counter[5m])) 而非 rate(sum(counter[5m])) |
| PromQL | 用 rate() 告警,别用 irate() |
irate() 太敏感,for 子句重置风险高 |
| PromQL | 时间窗口 ≥ 4× 抓取间隔 | 30s 抓取 → 至少 [5m] |
| 配置 | 设置 external_labels |
{cluster="us-east-1"} 区分多集群 |
| 配置 | 用 promtool check config 验证 |
部署前验证配置文件语法 |
| 配置 | 每个 job 设 sample_limit |
防止恶意或故障目标打爆 Prometheus |
| 存储 | 本地 15-30 天 + 远程长期存储 | 分层策略平衡查询速度和历史数据 |
| 告警 | 每条告警配置 runbook_url |
让 on-call 人员知道如何处理 |
| 告警 | 用 severity 标签分级 |
critical / warning / info 三级,方便 Alertmanager 路由 |
| 安全 | Node Exporter 9100 不暴露公网 | 仅允许 Prometheus 服务器 IP 访问 |
| 安全 | 用文件存储密码 | password_file 而非直接写在 yaml 里 |
| 运维 | 先测试再部署 | 在 Prometheus UI/Explore 中验证查询再建告警 |
| 运维 | 监控你的监控 | Prometheus 自监控 + Node Exporter 自监控 |
| 运维 | 定期检查 prometheus_tsdb_* |
关注存储增长、compaction 延迟、head block 大小 |
3. ⚡ 性能优化提示
| 优化项 | 说明 |
|---|---|
| 减少抓取间隔 | 非关键服务用 60s,关键服务用 15s |
| 减少标签基数 | metric_relabel_configs 中 drop 无用标签 |
| 降低指标数量 | drop 掉 go_*、process_* 等不关心的指标 |
| Recording Rules | 昂贵的聚合查询预计算,看板直接用结果 |
调低 max_block_duration |
2h 更适合频繁查询近期数据的场景 |
增加 --storage.tsdb.max-block-duration |
到 24h 或 36h 减少 compaction 频率 |
| 使用 SSD | Prometheus TSDB 对 IOPS 敏感 |
参考资料: