避坑指南:为什么你在 `relabel_configs` 里过滤不掉指标?

很多刚接触 Prometheus 的小伙伴在优化监控时,都会遇到一个令人困惑的"玄学"问题:

"我明明在配置文件里写了要丢弃 go_gc_duration_seconds 这个指标,为什么重载配置后,它依然活蹦乱跳地出现在数据库里?"

检查配置语法,没错;重启服务,没用。

原因只有一个:你放错了位置。

你把针对 指标名称(__name__ 的过滤规则,写在了 relabel_configs 里,而它其实应该待在 metric_relabel_configs 里。

今天这篇博文,我们就来彻底搞懂这两个配置块的区别,帮你避开这个 90% 的新手都会踩的坑。


🕵️‍♂️ 核心误区:把"事后清洗"当成了"事前拦截"

Prometheus 的抓取过程并不是"一蹴而就"的,它分为两个截然不同的阶段。理解这两个阶段,是掌握 Relabeling 的关键。

阶段一:目标发现与准备 (relabel_configs)

  • 时间点 :Prometheus 刚刚通过 K8s、DNS 或静态列表发现了一个目标(比如 192.168.1.5:9100),正准备发起 HTTP 请求之前
  • 手里有什么 :此时,Prometheus 手里只有目标的元数据(地址、端口、Pod 名字、节点标签等)。
  • 手里没有什么它还没有拿到任何具体的指标数据! 它根本不知道这个目标会暴露 http_requests_total 还是 go_gc_duration_seconds
  • 结论 :在这个阶段,__name__(指标名)这个标签甚至还不存在。你试图根据一个不存在的值去过滤,自然是无效的。

阶段二:数据解析与入库 (metric_relabel_configs)

  • 时间点 :Prometheus 已经成功连接目标,下载了 /metrics 接口的所有文本数据,正在逐行解析,准备存入内存之前
  • 手里有什么 :此时,每一行数据都被解析成了样本,拥有了明确的指标名(__name__)、标签集(Labels)和数值(Value)。
  • 能做什么 :现在 Prometheus 终于知道"哦,这一行是 go_gc_duration_seconds"。你可以基于此决定:"扔掉这一行" 或者 "删掉这一行的某个标签"
  • 结论 :只有在这个阶段,基于 __name__ 的过滤才会生效。

❌ 错误示范:为什么你的配置不生效?

看看下面这段配置,是不是觉得很眼熟?

yaml 复制代码
scrape_configs:
  - job_name: 'my-java-app'
    static_configs:
      - targets: ['localhost:8080']
    
    # ⚠️ 错误位置!这里还没有指标数据,__name__ 是空的
    relabel_configs:
      - source_labels: [__name__]
        regex: 'go_.*'
        action: drop

发生了什么?

  1. Prometheus 发现 localhost:8080
  2. 进入 relabel_configs 阶段。它尝试读取 __name__,发现是空的(或者未定义)。
  3. 正则匹配失败(或者不匹配),action: drop 不触发。
  4. Prometheus 继续发起 HTTP 请求,抓取所有数据。
  5. 数据解析完成,所有 go_ 开头的指标被原封不动地存入数据库。

结果:过滤失败,内存继续爆炸。


✅ 正确姿势:把刀用在刀刃上

要过滤具体的指标(如 go_.*, jvm_.*),必须使用 metric_relabel_configs

yaml 复制代码
scrape_configs:
  - job_name: 'my-java-app'
    static_configs:
      - targets: ['localhost:8080']
    
    # ✅ 正确位置!此时指标已解析,__name__ 有值
    metric_relabel_configs:
      - source_labels: [__name__]
        regex: 'go_.*'
        action: drop
      
      # 顺便再丢弃一些没用的 JVM 指标
      - source_labels: [__name__]
        regex: 'jvm_gc_pause_seconds.*'
        action: drop

现在的流程

  1. 抓取数据。
  2. 解析出一行 go_gc_duration_seconds{...} 0.05
  3. 进入 metric_relabel_configs
  4. 发现 __name__go_gc_duration_seconds,匹配正则 go_.*
  5. 触发 action: drop直接丢弃该行数据,不写入内存,不写入磁盘。

结果:完美过滤,资源节省。


🆚 深度对比:两张表看懂区别

为了让你以后不再混淆,请保存这张对比表:

特性 relabel_configs metric_relabel_configs
执行时机 抓取前 (Before Scrape) 抓取后,存储前 (After Scrape)
处理对象 Target (目标) Sample (样本/指标行)
__name__ 可用吗? 不可用 (此时还没抓到数据) 可用 (数据已解析)
主要用途 1. 筛选要抓取的目标 (如只抓特定 Pod)2. 重命名发现标签 (如 __meta_... -> pod)3. 构造静态标签 1. 过滤具体指标 (Drop/Keep __name__)2. 删除高基数标签 (LabelDrop)3. 修改样本值
性能优势 ⭐⭐⭐⭐⭐ (省去了网络请求和解析开销) ⭐⭐⭐ (省去了存储和索引开销,但已消耗带宽)
典型场景 "我只需要抓取名为 web-server 的 Pod" "我不需要 go_gc 指标" 或 "删掉 trace_id 标签"

💡 进阶技巧:什么时候用 relabel_configs 更优?

虽然 relabel_configs 不能过滤 __name__,但它在筛选目标方面效率更高。

场景 :你有 1000 个 Pod,但你只想监控其中名字包含 production 的 100 个 Pod。

  • 做法 A (错误) :在 metric_relabel_configs 里抓取所有 1000 个 Pod 的数据,然后根据指标过滤?不行,因为这是针对 Target 的筛选,不是针对指标的。
  • 做法 B (正确且高效) :在 relabel_configs 中直接丢弃那 900 个不需要的 Target。
yaml 复制代码
scrape_configs:
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      # 在发起任何 HTTP 请求之前,直接丢弃非 production 的 Pod
      # 这样连网络带宽和 CPU 解析都省下了!
      - source_labels: [__meta_kubernetes_pod_name]
        regex: '.*production.*'
        action: keep

最佳实践总结

  1. 先粗筛 :用 relabel_configs 决定**"抓谁"**(基于 Pod 名、IP、Namespace 等元数据)。
  2. 后精洗 :用 metric_relabel_configs 决定**"存什么"**(基于 __name__ 指标名、具体标签值)。

🔍 如何验证你的配置?

改完配置别盲目自信,用这两招验证:

  1. 语法检查(必做):

    bash 复制代码
    promtool check config prometheus.yml

    确保没有 YAML 格式错误。

  2. 查询验证

    重载配置后,去 Prometheus UI 的 Graph 页面:

    • 如果你过滤了 go_.*,查询 count({__name__=~"go_.*"})。如果返回 0No data,恭喜成功!
    • 如果你删除了标签,查询该指标并查看 Table 视图,确认该标签是否消失。

🎉 结语

Prometheus 的配置看似复杂,其实逻辑非常清晰:

  • relabel_configs 是门卫,决定谁可以进门(Target)。
  • metric_relabel_configs 是安检员,决定进门的人身上哪些东西可以带进去(Metrics & Labels)。

下次再想过滤指标名时,记得找安检员metric_relabel_configs),别在门口(relabel_configs)白费功夫了!

希望这篇博文能帮你解决疑惑。如果觉得有用,欢迎点赞收藏,转发给那些还在为 Prometheus 内存溢出头疼的运维同事!

相关推荐
DianSan_ERP6 分钟前
如何通过抖店订单接口实现订单状态管理与履约自动化?
运维·自动化
b***251131 分钟前
18650电池点焊机:电阻焊技术如何决定电池组的成败|深圳比斯特自动化
运维·自动化
原来是猿40 分钟前
网络计算器:理解序列化与反序列化(中)
linux·运维·服务器·网络·tcp/ip
前端老曹1 小时前
Docker 从入门到放弃:完整指南
运维·docker·容器
AOwhisky2 小时前
虚拟化技术学习笔记
linux·运维·笔记·学习·虚拟化技术
rabbit_pro3 小时前
Docker compose部署Ollama使用模型
linux·运维·docker
笑洋仟4 小时前
docker的overlay2目录占用磁盘空间很大,清理办法
运维·docker·容器
木雷坞4 小时前
2026 年 5 月国内可用 Docker 镜像源列表与配置方法
运维·docker·容器
2301_780789665 小时前
“数字珍珠港”再现:西北能源基地DNS篡改事件深度复盘与防护升级
运维·服务器·网络·tcp/ip·网络安全·智能路由器·能源
老王谈企服5 小时前
2026制造业供应链韧性提升,智能化将成为核心解决方案吗?基于实在Agent的端到端自动化实践
运维·人工智能·ai·自动化