4、采集管线架构设计:采集器、处理器、导出器三层架构,以及Terraform如何编排
SLI 口径采集管线是连接可观测数据源与 SLO 计算引擎的中间层。一个生产级的采集管线必须支持高并发接入、动态字段清洗、多后端路由,并且能够通过基础设施即代码(IaC)进行版本化管理。本章将拆解采集管线的三层标准架构,并展示 Terraform 如何通过模块化编排实现每一层的声明式部署。
4.1 三层架构总览
采集管线遵循 采集器(Collector)→ 处理器(Processor)→ 导出器(Exporter) 的线性数据流模型。每一层职责单一、可独立扩展,通过标准接口(gRPC / HTTP / 本地管道)进行数据传递。
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 |
max_retries、retry_on_failure 参数控制;同时建议在导出器前增加本地缓冲队列(如磁盘队列),防止后端抖动导致数据丢失。
4.5 Terraform 如何编排三层管线
Terraform 通过模块化组合,将采集器、处理器、导出器定义为独立的子模块,并通过 数据流依赖 和 配置注入 串联整个管线。编排的核心思路是:
- 定义全局变量: 如
collector_endpoint、processor_rules、exporter_backends。 - 实例化采集器模块: 传入端口、协议、资源限制。
- 实例化处理器模块: 引用采集器的输出地址,注入口径映射规则。
- 实例化导出器模块: 引用处理器的输出地址,配置后端连接信息。
- 输出管线拓扑: 通过
output暴露各层端点,供监控和告警系统使用。
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
}
}
depends_on 隐式推导模块依赖(基于输入引用),无需显式声明。但若模块间存在非数据依赖(如网络策略顺序),可使用 depends_on = [module.collector] 强制排序。
4.7 架构决策与避坑指南
| 决策点 | 推荐方案 | 反模式 |
|---|---|---|
| 采集器状态 | 无状态 + 水平扩展 | 有状态采集器导致扩缩容困难 |
| 处理器配置 | ConfigMap 热加载 + 版本化 | 硬编码在镜像中,无法动态调整 |
| 导出器重试 | 指数退避 + 本地磁盘缓冲 | 无限重试导致资源耗尽 |
| Terraform 状态 | 远程状态(S3/Consul)+ 锁 | 本地状态导致多人协作冲突 |
| 模块版本 | 使用 version 约束 + 注册表 |
直接引用 main 分支 |
limits.cpu 和 limits.memory),否则会抢占采集器资源,导致数据接入延迟。Terraform 中通过 resources 块为每个模块独立设置。
通过采集器、处理器、导出器的三层解耦,以及 Terraform 模块化编排,团队可以独立迭代每一层的配置、扩缩容和版本升级,同时保持整个管线的可观测性和可追溯性。下一层将深入处理器内部,详细讲解 SLI 口径映射规则引擎的设计与 Terraform 配置管理。