3. 采集架构设计:端到端SLI采集管道
SLI采集不是单点任务,而是一条从数据源到可视化面板的完整管道。设计合理的分层架构,能确保采集的实时性、准确性与可扩展性。本节将拆解四层模型:探针层、聚合器层、存储层与可视化层。
3.1 四层管道总览
端到端SLI采集管道遵循“采集 → 聚合 → 存储 → 展示”的经典时序数据处理模式。每一层职责清晰,层间通过标准协议解耦。
核心原则:探针只负责“采”,聚合器只负责“算”,存储层只负责“存”,可视化层只负责“展”。职责分离是管道可维护性的基石。
3.2 探针层:数据采集的“触手”
探针是管道的第一环,直接与目标系统交互。根据采集方式,探针分为三类:
| 探针类型 | 采集方式 | 典型SLI | 部署位置 |
|---|---|---|---|
| 主动探针 | 模拟用户请求(HTTP/gRPC/ICMP) | 可用性、延迟 | 边缘节点、CDN PoP |
| 被动探针 | 监听服务指标暴露端点(/metrics) | 请求速率、错误率、饱和度 | 应用侧边容器、Agent |
| 日志探针 | 实时解析结构化日志流 | 错误率、慢查询率 | 日志采集器(Fluentd/Logstash) |
实战建议:优先使用被动探针采集RED指标(Rate/Errors/Duration),主动探针作为“用户视角”的补充。避免对同一指标同时使用两种探针,防止数据重复。
3.3 聚合器层:数据清洗与预计算
原始探针数据通常高基数、高频率,直接写入存储层会导致性能灾难。聚合器层承担三个关键任务:
- 窗口聚合:将1秒级原始数据聚合为10秒/1分钟/5分钟窗口,降低数据量。
- 标签标准化:统一探针输出的标签命名(如
service_name→svc),消除异构探针的标签差异。 - 异常预标记:基于阈值或统计模型,在聚合阶段标记异常窗口,加速后续告警。
# 聚合器配置示例(伪代码)
aggregator:
window_size: 60s # 聚合窗口
input_protocol: "prometheus_remote_write"
output_protocol: "kafka"
label_normalization:
- from: "service_name"
to: "svc"
- from: "host_ip"
to: "instance"
anomaly_detection:
enabled: true
method: "z-score"
threshold: 3.0
3.4 存储层:时序数据的“基石”
SLI数据是典型的时序数据,推荐使用专用时序数据库(TSDB)。存储层设计需关注三个维度:
| 维度 | 推荐方案 | 说明 |
|---|---|---|
| 写入吞吐 | VictoriaMetrics / Thanos | 支持百万级时间线并发写入 |
| 数据保留 | 热存7天 + 冷存90天 | 热存用于实时告警,冷存用于SLO回溯 |
| 降采样策略 | 原始1s → 1m聚合 → 1h聚合 | 超过30天的数据自动降采样为1h粒度 |
避坑提示:不要将所有SLI指标都保留原始精度。对于99.9%的SLO回溯场景,1分钟粒度已经足够。保留原始1秒数据只会浪费存储并拖慢查询。
3.5 可视化层:从数据到决策
可视化层是管道的终点,也是SRE团队日常使用的界面。核心功能包括:
- SLO仪表盘:实时展示每个SLI的当前值、燃烧率、剩余错误预算。
- 多时间窗口对比:支持7天/30天/90天的SLI趋势叠加。
- 告警规则引擎:基于燃烧率(Burn Rate)触发告警,而非静态阈值。
- 报表导出:定期生成SLO达成率报告,用于团队复盘。
3.6 管道关键设计决策
在落地采集管道时,以下决策直接影响系统稳定性:
| 决策点 | 推荐方案 | 不推荐方案 |
|---|---|---|
| 探针与聚合器通信 | gRPC Stream 或 Kafka | HTTP短连接(高延迟、高开销) |
| 聚合器部署模式 | 无状态水平扩展 + 一致性哈希 | 有状态主从模式(单点瓶颈) |
| 存储层写入模型 | 批量写入(每批1000点) | 单点逐条写入(TPS受限) |
| 可视化层查询 | PromQL 或 类SQL查询 | 全量数据拉取后前端聚合 |
架构检查清单:
✅ 探针层是否支持热更新配置?
✅ 聚合器层是否具备背压(Backpressure)机制?
✅ 存储层是否配置了数据保留与降采样策略?
✅ 可视化层是否支持燃烧率告警而非静态阈值?
✅ 探针层是否支持热更新配置?
✅ 聚合器层是否具备背压(Backpressure)机制?
✅ 存储层是否配置了数据保留与降采样策略?
✅ 可视化层是否支持燃烧率告警而非静态阈值?
四层架构并非一成不变。在小型团队或初期阶段,可以将聚合器与存储层合并;在超大规模场景下,甚至需要引入缓冲层(如Kafka)来削峰填谷。但无论规模如何,职责分离与标准协议始终是设计的主线。