login
解决Prometheus-adapter内存溢出问题
2025/08/12·StepFun can make mistakes, check important info.
67923d082e2246d2ae5b9e7a816fc94f~tplv-9xxiciwj9y-image.image
Reason
思考过程

首先,用户提供的信息是关于Prometheus-adapter规则导致指标(metrics)暴涨的问题。具体来说,有两个规则被提及:

  1. 第一个规则:avg_over_time(hpa.num_requests_running{namespace!="",pod!=""}[1m])
    这个规则来自Prometheus-adapter的配置。

  2. 进一步拆分后,底层对应的规则:avg_over_time(ray_serve_replica_processing_queries{cluster="sh-b-shaipower"}[1m])
    这个规则是已经存在的,不是新添加的。

问题的根源是服务 step3-pdf-parser-mineru-model-v1-H800-0509 产生了大量的metrics,导致prometheus-adapter处理这些metrics时内存过大,最终出现内存溢出(OOM)。

此外,该任务是弹性任务,副本数多,且扩缩容频繁。用户建议观察该任务的独立大盘来监控。

我的任务是分析这个问题并提供解决方案。既然用户提到我是Step3,我应该基于这个上下文来推理。

关键点:

  • Prometheus-adapter 因为处理大量metrics而OOM。
  • metrics来自 ray_serve_replica_processing_queries 这个指标,特定于 cluster="sh-b-shaipower"
  • 服务 step3-pdf-parser-mineru-model-v1-H800-0509 是产生大量metrics的来源。
  • 该任务有多个副本,扩缩容频繁。

可能的解决方案方向:

  1. 减少metrics生成:检查为什么 step3-pdf-parser-mineru-model-v1-H800-0509 会产生大量metrics。可能优化该服务的指标上报逻辑,减少不必要的指标。
  2. 过滤或采样metrics:在Prometheus-adapter或Prometheus配置中,添加过滤规则,只收集必要的metrics,或者对高频metrics进行采样。
  3. 增加资源:为prometheus-adapter分配更多内存,但这不是根本解决方案,因为metrics数量可能持续增长。
  4. 优化查询规则:检查avg_over_time的使用是否合理。avg_over_time 会查询时间窗口内的所有数据点,如果指标频率高,可能会拉取大量数据。考虑缩短时间窗口或使用其他聚合函数。
  5. 分片或分区:如果可能,将metrics分区,让不同的prometheus-adapter实例处理不同的部分。
  6. 监控和告警:设置监控,当metrics数量或内存使用达到阈值时告警,以便提前干预。
  7. 弹性任务优化:由于任务是弹性的,副本多导致metrics多,考虑调整扩缩容策略,减少副本数波动,或者在副本缩容时清理旧metrics。

具体到规则:

  • 规则1:avg_over_time(hpa.num_requests_running{namespace!="",pod!=""}[1m])
    这个规则可能用于HPA(Horizontal Pod Autoscaler)的自动扩缩容决策。它计算过去1分钟内运行请求数的平均值。

  • 规则2:avg_over_time(ray_serve_replica_processing_queries{cluster="sh-b-shaipower"}[1m])
    这个规则是Ray Serve相关的,计算特定集群中处理查询的平均值。

问题在于,ray_serve_replica_processing_queries 指标可能被非常频繁地上报,导致时间序列数据量巨大。当prometheus-adapter查询这个指标时,需要处理大量数据点,导致内存消耗过高。

Prometheus-adapter 是用于将Prometheus指标暴露给Kubernetes的组件,比如供HPA使用。它从Prometheus拉取指标,然后根据配置的规则处理这些指标,提供自定义指标API。

当指标数量巨大时,Prometheus-adapter 的内存使用会激增,因为:

  • 它需要存储和处理时间序列数据。
  • 对于每个指标,它可能需要维护状态以进行查询。

根本原因似乎是 ray_serve_replica_processing_queries 指标产生了太多数据点。可能的原因:

  • 该指标有大量的标签(labels),导致时间序列基数(cardinality)爆炸。
  • 指标上报频率过高(scrape interval太短)。
  • 服务副本多,每个副本都上报指标,进一步增加数据量。

解决方案建议:

  1. 减少指标基数:检查 ray_serve_replica_processing_queries 指标的标签。移除不必要的标签,或者将高基数标签(如动态生成的ID)从指标中排除。使用Prometheus的聚合操作符来减少数据量,比如 sum() 代替 avg_over_time 如果适用。
  2. 调整scrape配置:在Prometheus的scrape配置中,增加scrape_interval,降低指标上报频率,但这可能影响监控精度。
  3. 使用recording rules:在Prometheus中预先定义recording rules,将原始指标聚合成更粗粒度的指标,然后让prometheus-adapter使用这些聚合后的指标。这样,adapter查询时数据量更小。
  4. 过滤指标:在scrape配置中使用metric_relabeling,只保留必要的指标或标签。
  5. 资源限制:为prometheus-adapter的容器设置更高的内存限制(requests和limits),并确保它可以在高负载下获得足够资源。但需要监控,避免OOM。
  6. 查询优化:在规则中,避免使用长时间窗口的avg_over_time。例如,[1m] 窗口可能太短,但如果指标频率高(如每秒上报),1分钟会有60个数据点;如果副本多,会有很多时间序列,导致大量数据点。考虑使用更长的窗口(如[5m])或使用其他函数如rate()irate() 来减少数据量。
  7. 服务端优化:在 step3-pdf-parser-mineru-model-v1-H800-0509 服务中,优化指标的上报逻辑。例如,只上报必要的指标,或者降低指标的上报频率。
  8. 使用更高效的数据存储或查询引擎:如果Prometheus本身是瓶颈,考虑使用VictoriaMetrics或M3DB等替代方案,它们在处理高基数指标时更高效。
  9. 监控独立大盘:如用户建议,创建专门监控该任务的Grafana大盘,使用低级别的指标来诊断问题。

对于prometheus-adapter,配置中可以调整:

  • rules.yaml 或相应的配置中,对特定规则添加过滤条件,只处理来自相关任务的指标。
  • 使用series_filter 在adapter配置中排除某些系列。

现在,作为Step3,我需要给出一个结构化的响应,包含分析和建议。

响应结构:

  1. 问题总结:重述问题以便确认。
  2. 根本原因分析:基于信息分析原因。
  3. 建议解决方案:列出可行的步骤。
  4. 后续步骤:建议如何实施或监控。

问题分析与解决方案建议

从您提供的信息来看,核心问题是 Prometheus-adapter 因处理过量 metrics 导致内存溢出(OOM),根源是服务 step3-pdf-parser-mineru-model-v1-H800-0509 生成了海量 metrics,且该任务副本多、扩缩容频繁。以下是对问题的拆解分析和解决方案建议:


1. 问题根因分析

  • 指标生成端
    服务 step3-pdf-parser-mineru-model-v1-H800-0509 持续产生大量 ray_serve_replica_processing_queries 指标(尤其是 cluster="sh-b-shaipower" 标签下的数据)。这可能是由于:

    • 指标 基数(cardinality)过高:如动态标签(如副本ID、时间戳)未被过滤,导致时间序列爆炸。
    • 指标 上报频率过高:例如服务副本数膨胀时,每个副本高频上报指标,加剧 Prometheus 拉取压力。
    • 指标 无过滤/聚合:原始指标未经过预处理,直接推送给 Prometheus-adapter。
  • Prometheus-adapter 端

    • 规则 avg_over_time(ray_serve_replica_processing_queries{cluster="sh-b-shaipower"}[1m]) 需要实时拉取并计算大量时间序列的1分钟窗口数据。若指标频率为秒级,1分钟会产生数十个数据点/序列,内存消耗随副本数线性增长。
    • 弹性任务的扩缩容频繁,导致指标数量波动剧烈,Prometheus-adapter 无法稳定处理负载。
  • 最终结果
    metrics 总量超过 Prometheus-adapter 内存上限,触发 OOM(Out of Memory)。


2. 解决方案建议

针对“减少指标生成量 + 优化 Prometheus-adapter 处理”双管齐下,优先低成本优化,再考虑架构调整:

▶ 第一步:抑制指标生成量(低成本优先)
  • 服务端优化(推荐)

    • step3-pdf-parser-mineru-model-v1-H800-0509 的代码中,减少指标上报频率(例如从秒级改为分钟级),或关闭非核心指标(如调试类指标)。
    • ray_serve_replica_processing_queries 指标添加 标签过滤:移除高基数标签(如动态生成的 replica_id),仅保留必要维度(如 cluster)。
      示例(Ray Serve 配置):
      python
  • Prometheus 层降基数

    • 在 Prometheus 的 scrape_configs 中添加 metric_relabeling,丢弃无关标签或指标:
      示例(prometheus.yml):
      yaml
    • 使用 recording rules 预聚合:在 Prometheus 中定义规则,提前聚合指标(如求和代替平均值),减少 adapter 处理量:
      示例(prometheus.rules.yaml):
      yaml
      随后修改 adapter 规则为 avg_over_time(ray_serve:processing_queries_total:sum[1m])
▶ 第二步:优化 Prometheus-adapter 处理(针对性调优)
  • 规则优化

    • 缩短时间窗口:将 [1m] 改为更长的窗口(如 [5m]),减少单次查询的数据点数量:
      修改后规则:
      yaml
    • 替换聚合函数:若业务允许,用 rate()irate() 代替 avg_over_time(),聚焦变化率而非绝对值(减少数据存储压力)。
  • 配置过滤
    在 Prometheus-adapter 的 rules.yaml 中,添加 series_filter,仅处理关键指标:
    示例(adapter 配置):

    yaml
  • 资源扩容(临时应急)
    为 Prometheus-adapter 的 Deployment 增加内存限制(如 memory: 4Gi),但需配合监控验证效果,避免长期 OOM。

▶ 第三步:架构与监控增强(长期治理)
  • 独立监控大盘(关键)
    按建议创建 step3-pdf-parser-mineru-model-v1-H800-0509 的专属 Grafana 大盘,监控以下指标:

    • 指标基数:prometheus_series_cache_entries(高值表示时间序列爆炸)。
    • Adapter 内存:process_resident_memory_bytes(关联 OOM 风险)。
    • 服务副本数:hpa.replicas(扩缩容波动与指标暴涨的关联)。
      目标:定位副本数、指标量、OOM 事件的关联,验证优化效果。
  • 弹性任务调优

    • 调整 HPA 的 扩缩容阈值(如 targetAverageValue: 100200),减少副本频繁变化。
    • 设置 稳定窗口behavior.scaleDown.stabilizationWindowSeconds),避免副本数在短时间内剧烈波动。
  • 技术栈升级(可选)
    若指标量持续增长,考虑迁移到 VictoriaMetricsM3DB 等高效时序数据库,它们对高基数场景支持更好。


3. 执行优先级

  1. 立即行动
    • 服务端添加标签过滤 + 缩短上报间隔(1 小时内可完成)。
    • 临时扩容 Prometheus-adapter 内存(10 分钟内生效)。
  2. 中期优化
    • 配置 recording rules 预聚合 + adapter 规则窗口延长(1 天内)。
    • 部署独立监控大盘(2 小时内)。
  3. 长期治理
    • 弹性任务 HPA 参数调优 + 技术栈评估(1 周内)。

4. 验证方法

  • 核心指标:观察 :memory:used_bytes{job="prometheus-adapter"} 是否回落。
  • 业务指标:HPA 扩缩容决策(kubectl get hpa)是否仍正常触发。
  • 日志监控:Prometheus-adapter 容器日志中 OOM 错误消失。

若需具体配置模板(如完整的 prometheus-adapter Deployment.yaml),可提供更多上下文,我会生成可落地的代码片段!