eBPF 采集存储与可观测性统一架构趋势
可观测性架构在过去五年经历了从"分治"到"统一"的深刻转变。各信号(指标、日志、追踪、Profiling)从独立的专用后端走向共享存储与统一数据模型,而 eBPF 作为新一代采集手段,为这一转变提供了前所未有的数据深度与广度。本文将聚焦四个维度:eBPF 采集存储设计、统一存储架构(LGTM 分治 vs ClickHouse 统一)、OpenTelemetry 统一数据模型、以及对象存储与存算分离的演进方向。
本文从存储架构视角审视 eBPF 在可观测性中的角色——数据采到后存哪、怎么存、存算分离如何演进。如需了解 eBPF 采集侧的实现细节(CO-RE、libbpf、Aya、协议解析、OOM 追踪),请参阅 eBPF 系列。
新手类比:eBPF 就像在高速公路上装了智能摄像头——不用修改任何车辆(内核代码),就能在检查点采集所有车辆的数据。传统监控需要在每辆车上安装传感器(修改应用代码),而 eBPF 在路面(内核)层面捕获一切,对经过的车辆完全透明。
下方动画展示 eBPF 数据如何从内核态流向用户态:
动画说明:上方动画展示 eBPF 数据管道:网络数据包或系统调用触发 eBPF 程序(通过 kprobe/tracepoint 挂载),数据写入内核 Ring Buffer,用户态 Agent 通过 mmap 读取后发送到后端。关键对比:传统插桩需要应用层 SDK 修改且无法看到内核事件,而 eBPF 在内核层透明捕获一切。
eBPF 采集存储
eBPF 将采集能力下推到内核态,带来前所未有的细粒度数据,但也是数据量的爆炸式增长。本节分析三个典型 eBPF 可观测性方案的存储设计。
Pixie — 基于 eBPF 的无侵入可观测性平台
Pixie 平台由三大组件构成[E1]:Vizier(数据平面,部署在被监控集群)、Cloud(控制平面)、Vizier Operator(Kubernetes Operator)。
- 数据不出集群:采集数据存储在集群节点内存中,默认不发送到任何中心化后端
- PEM 通过 eBPF 在内核态采集数据,本地内存短期存储(最长 24h),是所有集群数据的主要存储位置
- 多级管道架构:eBPF 采集 → PEM 预处理与聚合 → Kelvin 节点级到集群级聚合 → Query Broker 结果合并
flowchart TD
PEM["PEM<br/>eBPF 采集 + 本地内存 24h"]
K["Kelvin<br/>集群级聚合"]
QB["Query Broker<br/>结果合并"]
Cloud["Cloud<br/>控制平面"]
PEM --> K
K --> QB
Cloud -.->|不存储数据| PEM
Cloud -.->|不存储数据| K
style PEM fill:#4CAF50,color:#fff
style K fill:#2196F3,color:#fff
style QB fill:#9C27B0,color:#fff图 1:Pixie “采集即计算"架构。PEM(绿色)通过 eBPF 在内核态采集数据并存储在本地内存中,最长保留 24 小时。Kelvin(蓝色)执行集群级聚合,Query Broker(紫色)合并查询结果。Cloud 控制平面不存储数据,体现了"数据不出集群"的设计原则——只有查询结果而非原始数据被传输。
架构趋势洞察:Pixie 体现了"采集即计算"的设计——数据聚合在采集侧(PEM/Kelvin)完成,只有查询结果而非原始数据被传输[E1][E2]。
Cilium/Hubble — eBPF 网络可观测性
Hubble 构建在 Cilium 与 eBPF 之上,其 server 组件嵌入式运行在 Cilium Agent 中[E5]。
Flow 日志存储:用户态 Ring Buffer[E5]:
- Hubble 将 Cilium event monitor 的监控事件存入用户态 ring buffer 结构
- ring buffer 在内存中存储可配置数量的事件,buffer 满后覆盖最旧事件(FIFO 覆盖)
- 无锁设计:内部 buffer 长度是
2^n,采用原子操作而非锁机制
eBPF 数据采集特点
eBPF 采集的数据量极大,因此降量是核心挑战[E10]:
| 机制 | 特点 | 适用场景 |
|---|---|---|
| eBPF Ring Buffer | kernel 5.8+,单 buffer 多 CPU 共享,内存效率高 | 高吞吐事件流(推荐) |
| Perf Event | 每 CPU 独立 buffer | 兼容性场景 |
| Hash Map | 用于计数器等聚合状态 | 内核态聚合 |
内核态聚合策略[E10]:在内核计算摘要而非流式传输原始事件、智能采样。这一策略在 Pixie、Hubble、Inspektor Gadget 中均有体现——采集侧聚合 + 短期内存存储 + 按需查询传输结果。
统一存储架构(LGTM 分治 vs ClickHouse 统一)
Grafana Stack 的"分治"架构
Grafana Stack 采用每个信号类型一个专用后端的架构:Mimir(指标)、Loki(日志)、Tempo(追踪)、Pyroscope(持续性能剖析)[E11][E12]。各后端共享对象存储但数据库引擎独立。
flowchart TD
Mimir["Mimir<br/>Metrics"]
Loki["Loki<br/>Logs"]
Tempo["Tempo<br/>Traces"]
Pyro["Pyroscope<br/>Profiling"]
G["Grafana<br/>UI 关联层"]
Mimir --> G
Loki --> G
Tempo --> G
Pyro --> G
style Mimir fill:#2196F3,color:#fff
style Loki fill:#FF9800,color:#fff
style Tempo fill:#f44336,color:#fff
style Pyro fill:#9C27B0,color:#fff图 2a:Grafana LGTM 分治架构。每种信号类型对应专用后端——Mimir(蓝)、Loki(橙)、Tempo(红)、Pyroscope(紫)。各后端共享对象存储但数据库引擎彼此独立。跨信号关联发生在可视化层(Grafana)而非存储层[E16]。
ClickHouse 作为统一可观测性存储
ClickHouse 已成为可观测性存储引擎的事实标准,核心论点是"可观测性是数据分析问题,应像对待数据分析一样对待它”[E16]。
flowchart TD
GCH["Grafana"]
CH["ClickHouse<br/>统一列存"]
Signals["指标 / 日志 / 追踪<br/>/ Profiling"]
CH --> GCH
Signals --> CH
style CH fill:#4CAF50,color:#fff
style GCH fill:#2196F3,color:#fff图 2b:ClickHouse 统一存储架构。所有信号共用单一列存引擎,关联在存储层通过标准 SQL JOIN 实现[E18],避免了多库之间的数据冗余与 ETL 开销。
列存优势[E16]:
| 特性 | 对可观测性的价值 |
|---|---|
| 压缩 | 日志/trace 平均压缩 14 倍 |
| 快速聚合 | GROUP BY 聚合响应快 |
| 快速线性扫描 | 可扫描数十 GB/s(压缩态),替代倒排索引 |
| 高基数 | 列存从根本上解决高基数问题[E17] |
| SQL | 降低学习成本 |
5 步成本优化技术栈[E16]:
- 编解码器链式组合:Delta/DoubleDelta + ZSTD,约 50% 存储削减
- 分层存储:热数据 NVMe SSD,7 天后迁移 S3
- 主键优化:
ORDER BY (toStartOfMinute(Timestamp), Service) - 物化视图预聚合:数据到达时预计算聚合
- 异步插入:服务端缓冲,省去 Kafka
大规模实践验证:据 ClickHouse 官方 playbook,Anthropic、OpenAI、Tesla、Didi、Shopee 等采用 ClickHouse(注:以下案例数据来源为 ClickHouse 营销材料,未经独立核实)——Tesla 构建千万级行/秒摄入平台;OpenAI 将查询从分钟级降至毫秒级;Didi 从 ES 迁移实现 30% 成本下降+4 倍查询提速[E16]。
核心结论(3 源交叉验证):统一列存替代分治多库是明确趋势。ClickHouse 官方文档[E18]、ClickStack playbook[E16]、Parseable 对比[E19]均确认:单引擎统一存储消除数据重复、原生支持高基数、降低 TCO。
OpenTelemetry 统一数据模型
统一信号架构
OpenTelemetry 客户端按信号(Signal) 组织——每个信号提供一种专门的可观测能力(tracing、metrics、logs、baggage),信号间共享上下文传播子系统但功能独立[E25]。
OTLP 数据结构以 Resource + InstrumentationScope + Signal 的统一层级组织[E26][E25]:
flowchart TD
Resource["Resource<br/>service.name, k8s.pod.name"]
Scope["InstrumentationScope<br/>库名 + 版本"]
Metrics["Metrics"]
Logs["Logs"]
Traces["Traces"]
Profiles["Profiles"]
Resource --> Scope
Scope --> Metrics
Scope --> Logs
Scope --> Traces
Scope --> Profiles
style Resource fill:#9C27B0,color:#fff
style Scope fill:#2196F3,color:#fff
style Metrics fill:#4CAF50,color:#fff
style Logs fill:#4CAF50,color:#fff
style Traces fill:#4CAF50,color:#fff
style Profiles fill:#4CAF50,color:#fff图 3:OpenTelemetry 统一数据模型。Resource(紫色)捕获实体信息(service.name、k8s.pod.name),InstrumentationScope(蓝色)标识仪表化库,Metrics、Logs、Traces、Profiles 四大信号(绿色)共享统一的 Resource 与 InstrumentationScope 层级,实现跨信号的实体关联。
- Resource:捕获遥测所记录实体信息,可描述整个实体层级(云主机到容器到应用)
- InstrumentationScope:标识产生遥测的仪表化库
- Signal:Metrics/Logs/Traces/Profiles 四大信号共享统一的 Resource 与 InstrumentationScope
Profiles 信号(第四支柱):已成为 OpenTelemetry 的第四信号。profile 可记录采样时哪些 span 处于活跃状态,实现 profile 与 tracing 的关联[E27]。
Exemplar 机制
Exemplar 是连接指标与 trace 的桥梁:将指标数据点关联到示例 trace_id,使从延迟尖峰可直接跳转到代表性 trace[E28][E29]。
跨信号关联存储设计
flowchart TD
Exemplar["Metrics → Traces<br/>Exemplar(trace_id)"]
TraceID["Logs → Traces<br/>trace_id 注入"]
SpanProfile["Profiles → Traces<br/>活跃 span 记录"]
Unified["统一基础<br/>Resource +<br/>InstrumentationScope"]
Unified --> Exemplar
Unified --> TraceID
Unified --> SpanProfile
style Exemplar fill:#2196F3,color:#fff
style TraceID fill:#FF9800,color:#fff
style SpanProfile fill:#4CAF50,color:#fff
style Unified fill:#9C27B0,color:#fff图 4:跨信号关联机制。三条关联链路均建立在统一基础上:Metrics 通过 Exemplar 携带 trace_id 关联到 Traces(蓝);Logs 通过结构化日志注入 trace_id/span_id(橙);Profiles 记录采样时活跃 span(绿)。统一基础(紫)确保所有信号共享相同的 Resource + InstrumentationScope 模型。
| 关联链路 | 机制 | 存储设计要求 |
|---|---|---|
| Metrics → Traces | Exemplar(trace_id/span_id 附加到指标点) | 指标存储需支持 exemplar 字段存储与查询 |
| Logs → Traces | 结构化日志注入 trace_id/span_id 关联 ID | 日志存储需支持 trace_id 索引 |
| Profiles → Traces | Profile 记录采样时活跃 span | profile 存储需关联 span 上下文 |
| 统一基础 | Resource(实体层级)+ InstrumentationScope(库标识) | 所有信号共享相同 Resource 模型 |
存储层设计模式对比:LGTM 分库模式关联在可视化层通过复杂 join 实现;ClickHouse 统一存储模式用标准 SQL JOIN 在存储层原生关联[E16][E18]。
核心结论(3 源交叉验证):跨信号关联正从"UI 层 join"演进到"存储层原生关联"。OTel 规范[E25][E29]、ClickHouse 文档[E18]、社区实践[E28]共同确认。
对象存储与计算存储分离
对象存储(S3/GCS/Azure Blob)在可观测性中的角色从"归档冷存储"升级为主存储后端[E12][E14]:
- Tempo:trace 数据最终持久化到对象存储[E14]
- Mimir:基于 Prometheus TSDB block 持久化到对象存储[E13]
- Loki:采用 Thanos Object Storage Client 对齐存储配置[E12]
- ClickHouse:分层存储策略将冷数据迁移到 S3[E16]
Tempo 3.0 是计算存储分离的典型范例[E14]:写读解耦、Kafka 作为持久 WAL、对象存储连接读写路径。
sequenceDiagram
participant WP as WritePath
participant K as Kafka(WAL)
participant OS as ObjectStorage
participant RP as ReadPath
WP->>K: 持久 WAL
K->>OS: Block-builder 写入
RP->>OS: 冷数据查询
RP->>K: 热数据(Live-store)查询图 5:Tempo 3.0 存算分离写读模型。WritePath 将数据写入 Kafka 作为持久化 WAL,Block-builder 异步消费并构建 block 写入对象存储。ReadPath 对冷数据直接查询对象存储,对热数据从 Kafka(Live-store)读取,实现写读路径的完全解耦。
来源
[E1] [官方] Pixie Architecture: https://docs.px.dev/reference/architecture/
[E2] [二级资料] Pixie 组件详解: https://blog.csdn.net/gitblog_00394/article/details/150926117
[E3] [二级资料] Pixie vizier-pem pod running out of memory: https://knowledge.newrelic.com/s/article/4408761257623
[E5] [官方] Hubble internals (Cilium docs): https://docs.cilium.io/en/latest/internals/hubble/
[E10] [二级资料] eBPF Observability Architecture: https://calmops.com/software-engineering/ebpf-observability-architecture-next-generation-monitoring/
[E11] [官方] Grafana: The open and composable observability platform: https://grafana.com/
[E12] [官方] Grafana Loki 3.4: Standardized storage config: https://grafanacon.org/blog/2025/02/13/grafana-loki-3.4-standardized-storage-config-sizing-guidance-and-promtail-merging-into-alloy/
[E13] [官方] Grafana Mimir architecture: https://grafana.com/docs/mimir/v3.0.x/get-started/about-grafana-mimir-architecture/
[E14] [官方] About the Tempo architecture: https://grafana.com/docs/tempo/next/reference-tempo-architecture/about-tempo-architecture/
[E16] [官方] How to engineer cost-efficient open source observability with ClickHouse (ClickStack): https://clickhouse.com/resources/engineering/observability-cost-optimization-playbook
[E17] [二级资料] The high-cardinality trap: https://clickhouse.com/resources/engineering/high-cardinality-slow-observability-challenge
[E18] [官方] Использование ClickHouse для обеспечения наблюдаемости: https://clickhouse.com/docs/ru/use-cases/observability/introduction
[E19] [二级资料] ClickHouse vs Parseable: https://www.parseable.com/blog/clickhouse-vs-parseable
[E25] [官方] OpenTelemetry — Overview (specs): https://opentelemetry.io/docs/specs/otel/overview/
[E26] [二级资料] OpenTelemetry 实战:云原生可观测性三大支柱统一标准: https://blog.csdn.net/xyghehehehehe/article/details/159112652
[E27] [二级资料] What is OpenTelemetry? (Dash0): https://www.dash0.com/knowledge/what-is-opentelemetry
[E28] [二级资料] Semantics First: Correlating Signals with OpenTelemetry: https://www.thequietkernel.com/engineering/system-engineering/30-09-2025-obs-semantics/
[E29] [官方] Using exemplars (OpenTelemetry .NET metrics docs): https://opentelemetry.io/pt/docs/languages/dotnet/metrics/exemplars/