本节摘要:OpenTelemetry Collector 统一 receivers → processors → exporters:metrics 可 export 到 Prometheus Remote Write、Influx、Timescale、QuestDB;logs 走 Loki;traces 走 Tempo。Kubernetes 侧 Prometheus pull
/metrics;IoT 侧 Telegraf push Line Protocol。接入层是 relabel 与 cardinality 治理的第一道闸。
阅读完本节,你应当能够:
metric_relabel_configs 或 processor 删除高基数 label2015 年前应用 直连 TSDB 写入——与存储强耦合、失败即丢数。Agent 时代(Telegraf、node_exporter)解耦了应用,但标签策略分散各机。2020 年后 网格化采集 + OTel 把 metrics/logs/traces 统一经 Collector 路由,全局 attributes processor 可强制注入 env=prod、region=cn 并 drop pod_uid。
为什么「采集层是第一道闸门」?因为一旦数据带着高基数标签进入 TSDB,事后再清理就要经历「删 series → 重建索引 → 等待 compaction」的漫长周期,期间内存与查询还在持续受损。而在接入层做一次 relabel,成本只是配置文件的几行。治理前置,永远比事后清理便宜,这是本节所有实践的核心立场。
| 协议 / 方式 | 典型源 | 后端 | 写入模型 |
|---|---|---|---|
| Prometheus text | node_exporter | Prometheus pull | pull |
| Remote Write | Prometheus/OTel | VM/Cortex/Influx | push 批 |
| Line Protocol | Telegraf | Influx/QuestDB | push |
| OTLP gRPC | 应用 SDK | Collector → 多后端 | push |
| PostgreSQL COPY | ETL | Timescale | push 批 |
Collector 的配置本质是三段式:receivers 定义「数据从哪来」,processors 定义「路上做什么」,exporters 定义「送到哪去」。最常见的一个误区是只在 receivers 加协议、忘了 processors 做治理、exporters 随便填——结果数据是进去了,基数问题也进去了。下面这张表给出三段各自的常见组件:
| 环节 | 常见组件 | 典型作用 |
|---|---|---|
| receivers | otlp、prometheus、filelog | 接收 OTLP / scrape / 日志 |
| processors | batch、attributes、transform、memory_limiter | 攒批、增删标签、改字段名、限内存 |
| exporters | prometheusremotewrite、otlp、loki | 写入后端 |
ServiceMonitor 发现 Pod → scrape 15s → 本地 TSDB → remote_write 长期层。优势:服务端控采样率,客户端时钟不影响 timestamp。
receivers: otlp: protocols: { grpc: {}, http: {} } processors: batch: { timeout: 5s, send_batch_size: 1000 } attributes: actions: - key: deployment.environment value: production action: insert exporters: prometheusremotewrite: endpoint: http://victoriametrics:8428/api/v1/write service: pipelines: metrics: receivers: [otlp] processors: [batch, attributes] exporters: [prometheusremotewrite]
这个配置做的事:应用通过 OTLP 上报 metrics → Collector 每 5 秒或攒满 1000 条打一个包 → 全局注入 deployment.environment=production 标签 → 批量写入 VictoriaMetrics。注意 batch 处理器几乎是必开的,否则每条 OTLP 消息都单独转发,写入队列会被小包淹没。
OTel 的 metric 命名(如 http.server.request.duration)与 Prometheus 命名规则(snake_case、单位后缀)不一致,直接 remote write 会产生一堆奇怪的 metric 名。在 processor 里做一次 transform:
processors: transform: metric_statements: - context: metric statements: - set(metric.name, replace_pattern(metric.name, "\\.", "_")) - set(metric.name, replace_pattern(metric.name, "-", "_"))
这样 http.server.request.duration 会被规范成 http_server_request_duration,后续 Grafana 面板与告警规则都能按统一的命名约定工作。
metric_relabel_configs: - source_labels: [__name__] regex: "go_gc_.*" action: drop - regex: "pod_uid" action: labeldrop
某金融客户将 instance_ip 聚合为 host + service_group,时间线从 8.2 亿降至 4700 万(InfluxData 2023 案例)。
接入层选 pull 还是 push,取决于你的网络拓扑与客户端特性:
| 判断条件 | 选 pull | 选 push |
|---|---|---|
| 客户端可达性 | 服务端能访问客户端 | 客户端在 NAT/动态 IP 后 |
| 采样节奏控制 | 需要服务端统一控制 | 客户端自控节奏 |
| 集群数量 | 少而稳 | 海量、随时上下线 |
| 典型场景 | K8s、虚拟机 | IoT 边缘、车载 |

| 产品 | 原生接入 | 备注 |
|---|---|---|
| Prometheus | scrape + RW | 生态最丰 |
| InfluxDB | Telegraf/OTel/ILP | push 友好 |
| TimescaleDB | pgx/COPY/OTel | SQL 生态 |
| QuestDB | ILP/PG wire | 高 ingest |
Batch 必开:Collector 无 batch 时写入队列 write_queue_length 积压,WAL fsync 延迟飙升。
Pull vs Push:动态 IP 边缘设备用 push;K8s 内服务发现用 pull。
多后端 export:同一 OTLP 管道可 fan-out 到 VM(监控)与 Timescale(分析),避免双 SDK 埋点。
接入层改动虽小,影响面却是全链路,上线前建议过一遍清单:协议是否配了 gRPC 与 HTTP 双通道;batch 超时与批量大小是否与后端写入能力匹配;attributes 是否注入了环境标签;高基数属性(pod_uid、request_id 类)是否已 drop;metric 命名是否经过 transform 规范化;queue 与 memory_limiter 是否设置了上限。每一项对应一类线上事故,逐项打勾能省下大量排障时间。
⚠️ 常见坑:OTel metric name 与 Prometheus 命名规则冲突——需
transformprocessor 规范化。
💡 关键直觉:接入层决定「脏数据进不进库」——比事后删 series 便宜三个数量级。
pod_uid 必须 drop 而不是保留?给出量化后果。下一节估算集群规模与关键告警指标。