三个主角与分工 · Prometheus、OTel Collector、Grafana
本专栏基于三份真实源码。这一章介绍它们各自是什么、在链条里占哪一段、为什么恰好是这三个——以及一个关键区分:OpenTelemetry 是标准,Collector 只是它的一个实现。
三个主角与分工 · Prometheus、OTel Collector、Grafana
上一章那条“指标的一生”上,站着三个主角。这一章正式介绍它们——它们不是竞品,而是同一条链条上的三段,各自解决一个不同的难题。
一句话分工
| 项目 | 版本 | 一句话 | 解决的难题 |
|---|---|---|---|
| Prometheus | 3.13.1 | 指标的采集 + 存储 + 查询引擎 | 海量时序数据怎么存得下、查得快 |
| OTel Collector | 0.156.0 | 厂商中立的统一管道 | 数据怎么被灵活地运输与加工 |
| Grafana | 13.1.0 | 观测端:可视化、探索、告警 | 数据怎么变成人能看懂的东西 |
采集与存储(Prometheus)、运输与加工(Collector)、展示与告警(Grafana)——三段拼起来才是一套完整的可观测性系统。
Prometheus:指标支柱的事实标准
Prometheus 的历史地位在于:它不只是一个软件,它定义的数据模型和查询语言成了整个行业的事实标准。
- 数据模型 —— “指标名 + 标签集 = 一条时间序列”这个模型被广泛采纳,连后来的 OpenTelemetry 也要兼容它。
- 暴露格式 ——
/metrics的文本格式后来标准化为 OpenMetrics,几乎所有中间件(数据库、消息队列、网关)都原生支持“吐一个 Prometheus 格式的端点”。 - PromQL —— 成了时序查询的通用语,VictoriaMetrics、Thanos、Mimir、云厂商的托管服务全都兼容它。
换句话说:即使你不用 Prometheus 这个进程,你大概率仍在用它的模型和语言。 这就是为什么本专栏花两个部分(TSDB + PromQL)深挖它的内核——你学的不是一个工具,是这个领域的通用语。它是 CNCF 继 Kubernetes 之后第二个毕业的项目,足见其地位。
Prometheus 的源码组织得极清晰,目录名基本就是那条数据链路:
prometheus-v3.13.1/
├── discovery/ 服务发现:去抓谁
├── scrape/ 抓取循环:怎么抓
├── storage/ 存储抽象层(Appender / Querier 接口)
├── tsdb/ 时序数据库内核 ← 相当硬核,含 docs/format/ 磁盘格式规范
├── promql/ 查询引擎(parser + engine)
├── rules/ 规则引擎:告警与预聚合
├── model/ 数据模型(labels、时间戳等)
├── config/ 配置
└── web/ HTTP API 与自带 UIOTel Collector:先分清“标准”和“实现”
这里有个极常见的混淆,必须先掰开:
OpenTelemetry(OTel)是一套标准 + 一族 SDK**;Collector 只是它生态里的一个组件。两者不是一回事。**
- OpenTelemetry 标准 —— 规定了三大支柱的数据模型、语义约定(比如 HTTP 请求该用哪些属性名)、以及传输协议 OTLP。这层是纸面规范。
- OTel SDK —— 各语言的埋点库(Java/Go/Python/...),让你在代码里产生符合标准的数据。
- OTel Collector —— 一个独立的进程,负责接收、加工、导出数据。它不是必须的(SDK 可以直连后端),但在生产里几乎总会用上——原因见下。
本专栏读的源码是 Collector(opentelemetry-collector-v0.156.0),但会顺带讲清标准和 OTLP 协议(第 5、6 部分)。记住:OTel 最大的价值其实是“标准”——它让埋点和后端解耦,你换后端不用重新埋点。
Collector 存在的理由,是一个朴素的工程问题:
N 个数据源 × M 个后端 = N×M 种对接。加一个中转站,就变成 N+M。 这就是 Collector:它站在中间,接收各种格式(OTLP、Prometheus、Jaeger、Fluent...)、加工(过滤、改标签、批量、采样、脱敏)、导出到各种后端。
它的组件模型极其规整,源码目录一目了然:
opentelemetry-collector-v0.156.0/
├── receiver/ 接收器:数据从哪进来
├── processor/ 处理器:中间怎么加工
├── exporter/ 导出器:数据往哪出去
├── connector/ 连接器:把一条管道的输出接到另一条的输入
├── extension/ 扩展:不碰数据的辅助能力(健康检查、认证等)
├── consumer/ 消费者接口:组件间怎么传数据(背压在这)
├── pdata/ 内部数据模型:三大支柱在内存里长什么样
├── pipeline/ 管道定义
└── service/ 服务编排(管道图的构建在这)receiver → processor → exporter 是最经典的三段式。但有个反直觉的事实:Collector 的管道实际上是一张 DAG,靠拓扑排序构建和启动,而不是简单的线性链——第 5 部分会打开 service/internal/graph/graph.go 看这件事。
Grafana:观测端
三者里 Grafana 最“面向人”:前两个负责把数据搞对,它负责把数据变成人能理解的东西。
- 数据源抽象 —— Grafana 本身不存数据,它是个前端 + 查询代理:把 Prometheus、Loki、Elasticsearch、各种数据库都抽象成“数据源”,用统一的方式查询和展示。这个抽象是它能一统可视化江湖的关键。
- 可视化与探索 —— 面板、仪表盘,以及 Explore(临时查询、顺着数据往下挖)。
- 统一告警 —— 近年 Grafana 把告警也收了进来(unified alerting),可以跨数据源告警。
Grafana 的源码是三者里最大的(~1.5 万个 Go/TS 文件),而且是前后端混合(Go 后端 + React 前端):
grafana-v13.1.0/
├── pkg/ Go 后端(API、数据源代理、告警、认证...)
├── public/ 前端(React/TypeScript)
├── apps/ 较新的应用化模块
└── conf/ 配置第 7 部分会挑它最有代表性的部分讲(数据源抽象、查询流、告警),而不是通读——1.5 万个文件里,大部分是业务和 UI,值得学的是那几个核心抽象。
为什么恰好是这三个
因为它们各自代表了可观测性的一个根本问题**,而且都是各自领域的头部实现:**
- Prometheus → “数据怎么存好查好”。这是算法与数据结构问题(压缩、索引、LSM),最有技术含量,也最能学到硬功夫。
- Collector → “数据怎么被灵活地运输”。这是软件架构问题(插件化、管道、背压、DAG),是学“如何设计可扩展系统”的绝佳样本。
- Grafana → “数据怎么被人理解”。这是抽象与产品问题(把千差万别的后端统一成一个心智模型)。
三个项目,三种不同性质的工程难题——这也是为什么读这三份源码的收获,远超“学会用监控”。它们分别是存储引擎、数据管道、统一抽象层的优秀范本,这些模式在别的领域一样通用。
小结与下一章
三个主角是同一条链条上的三段:Prometheus(3.13.1,指标的采集+存储+查询;它的数据模型 / 暴露格式 / PromQL 已成事实标准,学的是通用语)、OTel Collector(0.156.0,厂商中立的统一管道,把 N×M 对接变 N+M;注意 OTel 是标准、Collector 只是其一个组件)、Grafana(13.1.0,观测端:数据源抽象 + 可视化 + 统一告警)。选这三个,因为它们分别代表存储引擎 / 数据管道 / 统一抽象层三类不同性质的工程难题。
三份源码加起来上万个文件,怎么读才不迷路?下一章给方法。👉 怎么读这三份源码。
参考资料
- [1] Prometheus 源码 v3.13.1(
VERSION文件确认)、目录结构discovery/、scrape/、tsdb/、promql/、rules/。 - [2] OpenTelemetry Collector 源码 v0.156.0,目录
receiver/、processor/、exporter/、connector/、extension/、consumer/、pdata/、service/。 - [3] Grafana 源码 v13.1.0,目录
pkg/(Go 后端)、public/(前端)。