3. 指标采集核心概念:Pull模型 vs Push模型,Prometheus与OpenTelemetry的对比
在弹性伸缩指标采集链路中,数据采集模型决定了整个系统的架构形态、可靠性边界与运维复杂度。本章深入剖析 Pull(拉取)与 Push(推送)两种模型的设计哲学,并对比 Prometheus 与 OpenTelemetry 在指标采集上的核心差异。
3.1 Pull 模型:服务端主动拉取
Pull 模型由监控系统(如 Prometheus Server)定期向目标端点(Exporter)发起 HTTP 请求,主动获取指标数据。目标服务只需暴露一个 /metrics 端点,无需关心数据去向。
核心特征:
- 服务发现驱动:监控系统通过服务发现(Kubernetes、Consul、DNS SRV)动态获取目标列表。
- 数据一致性:每个采集周期内,监控系统对同一目标只拉取一次,避免重复数据。
- 天然去中心化:目标服务无需配置数据接收端,降低业务代码耦合。
3.2 Push 模型:客户端主动推送
Push 模型由业务服务或 Agent 主动将指标数据发送到中央收集器(如 Pushgateway、OpenTelemetry Collector)。服务端被动接收,无需感知数据源。
⚠️ 适用场景与风险:
- 短生命周期任务:批处理、CronJob、Serverless 函数,任务结束后无法被 Pull。
- 网络隔离环境:目标无法被监控系统直接访问,但可以主动外连。
- 风险:推送频率过高可能导致收集器过载;数据重复或丢失时难以追溯。
3.3 Pull vs Push 核心对比
| 对比维度 | Pull 模型 | Push 模型 |
|---|---|---|
| 控制方 | 监控系统控制采集节奏 | 数据源控制发送节奏 |
| 目标可见性 | 需要服务发现或静态配置 | 无需服务发现,数据源主动上报 |
| 数据重复 | 天然避免,每个周期拉取一次 | 容易重复,需幂等或去重机制 |
| 背压处理 | Server 控制并发,天然背压 | 需客户端限流或 Collector 降级 |
| 短任务支持 | 差,任务结束后无法拉取 | 好,任务结束前推送即可 |
| 网络要求 | 监控系统可访问目标 | 目标可访问收集器 |
| 典型代表 | Prometheus + Exporter | OpenTelemetry + Collector |
3.4 Prometheus 与 OpenTelemetry 的指标采集对比
Prometheus 是 Pull 模型的标杆实现,而 OpenTelemetry(OTel)提供了更灵活的 Push/Pull 双模能力。两者在指标采集上的差异直接影响弹性伸缩链路的选型。
| 对比维度 | Prometheus | OpenTelemetry |
|---|---|---|
| 采集模型 | 原生 Pull,支持 Push(通过 Pushgateway) | 原生 Push,支持 Pull(通过 OTel Collector) |
| 数据模型 | Metric 四元组:Name、Labels、Value、Timestamp | Metric + Span + Log 统一模型,支持 Exemplar |
| 协议 | Prometheus Exposition Format(文本/Protobuf) | OTLP(gRPC/HTTP Protobuf) |
| 服务发现 | 内置 Kubernetes、Consul、DNS 等 | 依赖 Collector 配置或第三方发现 |
| 聚合能力 | Recording Rules 预聚合 | Collector Processor 实时聚合 |
| 生态集成 | Exporter 生态丰富,但非 OTel 原生 | OTel SDK 原生集成,支持多语言 |
| 弹性伸缩适配 | 适合已知端点、稳定集群 | 适合动态任务、Serverless、边缘场景 |
3.5 弹性伸缩场景下的选型建议
💡 实践建议:
- 稳态集群(Kubernetes Node/Container):优先使用 Prometheus Pull 模型,利用内置服务发现,降低运维复杂度。
- 短任务与 Serverless:使用 OpenTelemetry Push 模型,通过 OTel Collector 接收并转发到 Prometheus 或后端存储。
- 混合架构:采用 OTel Collector 作为统一网关,同时支持 Pull(从 Exporter 拉取)和 Push(从 SDK 接收),再通过 Prometheus Remote Write 写入。
# 混合架构示例:OTel Collector 配置片段
receivers:
prometheus: # Pull 模式:从 Exporter 拉取
config:
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
otlp: # Push 模式:接收 OTel SDK 数据
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
timeout: 1s
exporters:
prometheusremotewrite:
endpoint: "http://prometheus:9090/api/v1/write"
service:
pipelines:
metrics:
receivers: [prometheus, otlp]
processors: [batch]
exporters: [prometheusremotewrite]
选择 Pull 还是 Push,本质是控制权与灵活性的权衡。在弹性伸缩链路中,建议以 Pull 为主处理稳态负载,以 Push 为辅处理动态任务,通过 OTel Collector 实现统一接入层。