4、采集管线架构设计:采集器、处理器、导出器三层架构,以及Terraform如何编排

SLI 口径采集管线是连接可观测数据源与 SLO 计算引擎的中间层。一个生产级的采集管线必须支持高并发接入、动态字段清洗、多后端路由,并且能够通过基础设施即代码(IaC)进行版本化管理。本章将拆解采集管线的三层标准架构,并展示 Terraform 如何通过模块化编排实现每一层的声明式部署。

4.1 三层架构总览

采集管线遵循 采集器(Collector)→ 处理器(Processor)→ 导出器(Exporter) 的线性数据流模型。每一层职责单一、可独立扩展,通过标准接口(gRPC / HTTP / 本地管道)进行数据传递。

核心原则: 采集器只负责数据接入与初步校验;处理器专注数据变换与口径计算;导出器仅处理序列化与路由。任何跨层逻辑耦合都会破坏模块化能力。
采集管线三层架构总览 采集管线三层架构总览 采集器 Collector 数据接入 · 初步校验 处理器 Processor 变换 · 口径计算 导出器 Exporter 序列化 · 路由 各层职责说明 • 采集器:支持 Prometheus Remote Write、OTLP、Syslog、自定义 Agent 等协议接入。 • 处理器:执行标签重写、指标聚合、SLI 口径映射、降采样、异常检测预处理。 • 导出器:将处理后的数据写入 Prometheus、Thanos、VictoriaMetrics、Kafka 或 S3。

4.2 采集器层:多协议接入与生命周期管理

采集器是管线的入口,负责接收来自不同数据源的原始指标。在生产环境中,采集器通常以无状态服务集群的方式部署,通过 ServiceMonitor 或 PodMonitor 动态发现目标。

协议/源 典型端口 数据格式 Terraform 资源示例
Prometheus Remote Write 19291 Snappy 压缩 Protobuf helm_release.prometheus
OTLP gRPC 4317 OTel Proto kubernetes_deployment.otelcol
OTLP HTTP 4318 JSON / Protobuf kubernetes_service.otelcol
Syslog / TCP 514 / 601 RFC 5424 docker_container.rsyslog
自定义 Agent 9100 自定义 Protobuf nomad_job.custom_agent
最佳实践: 采集器层应配置独立的健康检查端点(/health)和就绪探针(/ready),Terraform 通过 kubernetes_deployment 的 liveness_probe 和 readiness_probe 块自动注入。

4.3 处理器层:口径映射与数据变换

处理器是管线的核心逻辑层。SLI 口径的差异(例如:99 分位延迟 vs 平均延迟、错误码范围定义)在此层通过规则引擎或 DSL 脚本实现。处理器必须支持热加载配置,避免重启导致数据丢失。

常见的处理器类型包括:

  • 标签处理器: 重命名、删除、添加标签(例如将 service_name 统一为 service)。
  • 聚合处理器: 按时间窗口计算 P50/P90/P99、速率、增量。
  • 口径映射处理器: 将原始指标名映射为 SLI 标准名称(如 http_requests_total → sli:http:requests:count)。
  • 降采样处理器: 对高基数指标进行预聚合,减少存储成本。
  • 过滤处理器: 丢弃不符合 SLI 口径的指标(如非生产环境数据)。
# Terraform 中定义处理器配置(以 OpenTelemetry Collector 为例)
resource "kubernetes_config_map" "otel_processor" {
  metadata {
    name      = "otel-processor-config"
    namespace = "observability"
  }

  data = {
    "processor.yaml" = yamlencode({
      processors = {
        batch = {
          timeout = "5s"
          send_batch_size = 10000
        }
        memory_limiter = {
          check_interval = "1s"
          limit_mib      = 512
        }
        filter = {
          metrics = {
            include = {
              match_type = "regexp"
              metric_names = ["sli:.*"]
            }
          }
        }
        transform = {
          metric_statements = [
            {
              context = "datapoint"
              statements = [
                "set(attributes[\"sli_version\"], \"v2\")",
                "set(metric.name, Concat([\"sli:\", metric.name], \":\"))"
              ]
            }
          ]
        }
      }
    })
  }
}

4.4 导出器层:多后端路由与高可用写入

导出器负责将处理后的 SLI 数据写入存储后端。生产环境通常采用 主写 + 灾备 或 扇出(Fan-out) 模式,确保数据不因单点故障而丢失。

后端类型 协议 适用场景 Terraform 编排方式
Prometheus Remote Write 短期存储、告警 helm_release.prometheus + values
Thanos gRPC / Object Store 长期存储、全局视图 module.thanos
VictoriaMetrics Remote Write / Influx 高并发写入、低成本 helm_release.victoria_metrics
Kafka OTLP / Protobuf 异步缓冲、流处理 kafka_topic.sli_metrics
S3 / GCS Parquet / ORC 离线分析、合规归档 aws_s3_bucket.sli_archive
注意: 导出器层必须配置重试与背压机制。Terraform 中可通过 max_retries、retry_on_failure 参数控制;同时建议在导出器前增加本地缓冲队列(如磁盘队列),防止后端抖动导致数据丢失。

4.5 Terraform 如何编排三层管线

Terraform 通过模块化组合,将采集器、处理器、导出器定义为独立的子模块,并通过 数据流依赖 和 配置注入 串联整个管线。编排的核心思路是:

  1. 定义全局变量: 如 collector_endpoint、processor_rules、exporter_backends。
  2. 实例化采集器模块: 传入端口、协议、资源限制。
  3. 实例化处理器模块: 引用采集器的输出地址,注入口径映射规则。
  4. 实例化导出器模块: 引用处理器的输出地址,配置后端连接信息。
  5. 输出管线拓扑: 通过 output 暴露各层端点,供监控和告警系统使用。
Terraform 编排采集管线拓扑 Terraform 编排采集管线拓扑 module "collector" 采集器模块 module "processor" 处理器模块 module "exporter" 导出器模块 配置注入与依赖关系 1. collector 输出 collector_endpoint → processor 的 input_endpoint 2. processor 输出 processor_endpoint → exporter 的 input_endpoint 3. 全局变量 var.sli_rules 注入 processor 模块;var.backend_config 注入 exporter 模块 Terraform 输出(output) • output "pipeline_endpoints" → 暴露 collector、processor、exporter 的访问地址 • output "pipeline_health" → 通过 http_health_check 数据源验证各层状态

4.6 模块化编排示例代码

以下是一个完整的 Terraform 根模块示例,展示如何调用三个子模块并传递依赖:

# main.tf - 采集管线根模块
module "collector" {
  source = "./modules/collector"

  namespace       = var.namespace
  collector_ports = var.collector_ports
  replicas        = var.collector_replicas
}

module "processor" {
  source = "./modules/processor"

  namespace       = var.namespace
  input_endpoint  = module.collector.endpoint  # 依赖采集器输出
  sli_rules       = var.sli_rules              # 口径映射规则
  processor_cpu   = var.processor_cpu
}

module "exporter" {
  source = "./modules/exporter"

  namespace        = var.namespace
  input_endpoint   = module.processor.endpoint  # 依赖处理器输出
  backend_config   = var.backend_config         # 后端连接信息
  exporter_retries = var.exporter_retries
}

output "pipeline_endpoints" {
  value = {
    collector = module.collector.endpoint
    processor = module.processor.endpoint
    exporter  = module.exporter.endpoint
  }
}

output "pipeline_health" {
  value = {
    collector = module.collector.health_status
    processor = module.processor.health_status
    exporter  = module.exporter.health_status
  }
}
关键点: Terraform 通过 depends_on 隐式推导模块依赖(基于输入引用),无需显式声明。但若模块间存在非数据依赖(如网络策略顺序),可使用 depends_on = [module.collector] 强制排序。

4.7 架构决策与避坑指南

决策点 推荐方案 反模式
采集器状态 无状态 + 水平扩展 有状态采集器导致扩缩容困难
处理器配置 ConfigMap 热加载 + 版本化 硬编码在镜像中,无法动态调整
导出器重试 指数退避 + 本地磁盘缓冲 无限重试导致资源耗尽
Terraform 状态 远程状态(S3/Consul)+ 锁 本地状态导致多人协作冲突
模块版本 使用 version 约束 + 注册表 直接引用 main 分支
常见陷阱: 处理器层如果执行高 CPU 消耗的口径计算(如正则匹配、复杂聚合),必须配置独立的资源限制(limits.cpu 和 limits.memory),否则会抢占采集器资源,导致数据接入延迟。Terraform 中通过 resources 块为每个模块独立设置。

通过采集器、处理器、导出器的三层解耦,以及 Terraform 模块化编排,团队可以独立迭代每一层的配置、扩缩容和版本升级,同时保持整个管线的可观测性和可追溯性。下一层将深入处理器内部,详细讲解 SLI 口径映射规则引擎的设计与 Terraform 配置管理。