Prometheus调优:干掉高基数和慢查询

运维不是请客吃饭,Prometheus调优就得快准狠。今天记录我调优的一点内容。

一、PromQL优化三斧头

  1. 砍掉无用计算
    • 所有查询必须带标签过滤,别让Prometheus扫全表
      # 烂代码
      sum(rate(http_requests_total[5m])) 
      # 正确姿势
      sum(rate(http_requests_total{cluster="prod",service!~"test-.*"}[5m]))
      
  2. 预计算
    • 高频查询全做成 Recording Rules ```yaml

      prometheus.yml 配置示例

    • record: service:http_errors:rate5m expr: sum(rate(http_requests_total{status=~”5..”}[5m])) by (service) ```
  3. 函数选型要精准
    • 拒绝count()滥用,数值计算只用sum()
    • rate()irate()的区别:前者看趋势,后者抓毛刺

二、高基数指标

什么是高基数?

  • 一个指标标签组合超过500个时间序列就是高基数
  • 典型案例:把user_id当标签。

当某个标签的值具备以下特征时,就会引发高基数

  1. 动态生成:如用户ID、SessionID、TraceID、IP地址
  2. 不可预测数量:如错误信息error_message(可能无限增长)
  3. 高唯一性:如订单号、UUID

用这个PromQL量化风险:

# 直接找出Top10问题指标
topk(10, count by (__name__)({__name__=~".+"}))

# 查看单个指标的时间序列数量
count({__name__="your_metric_name"})

# 按标签维度分析
count by (label_name)({__name__="your_metric_name"})

风险阈值参考(根据集群规模调整)

时间序列数量 风险等级 处理建议
< 500 安全 无需处理
500-2000 警告 监控增长趋势
> 2000 危险 必须立即优化标签设计

tips:

  1. 动态标签死刑名单 永远不要用作指标标签

    user_id, ip, session_id, trace_id, request_id, 
    order_no, email, phone, uuid, error_message
    
  2. 安全标签范例 这些标签值可控,放心使用:

    status_code(如200/404/500), 
    http_method(GET/POST), 
    env(prod/stage/dev), 
    region(固定机房编号)
    
  3. 紧急止血方案 发现高基数指标后立即执行:

    # prometheus.yml 配置
    metric_relabel_configs:
      - source_labels: [user_id]  # 要清理的标签
        regex: (.+)
        action: labeldrop        # 直接丢弃该标签
    

三、性能监控三板斧

  1. 内存防线
    # 当内存突破16GB立即告警
    prometheus_tsdb_head_series > 10000000
    
  2. 慢查询追杀令
    # 查询延迟超过2秒的全给我记下来
    rate(prometheus_engine_query_duration_seconds_sum{slice="query"}[1m]) > 2
    
  3. 存储健康检查
    # 直接分析TSDB状态
    promtool tsdb analyze /data/prometheus/wal
    

四、巡检

  • 每周必查topk(10, count by (__name__)({__name__=~".+"}))
  • 发现高基数指标,24小时内必须解决
  • 查询超过1秒的统统优化

多维度优化降低Prometheus资源消耗的实践