架构与服务发现:TSDB、采集与集成
基于 Prometheus 3.x · 核于 2026-08
速查
- 架构组件:①Prometheus Server(核心:采集 + TSDB + PromQL 引擎);②Exporters/Client(暴露
/metrics,如 node_exporter/mysqld_exporter);③Pushgateway(短任务中转);④Service Discovery(K8s/Consul/DNS 动态发现目标);⑤Alertmanager(告警路由);⑥Grafana(可视化)。 - Pull 采集循环:SD 给目标列表 →
relabel_configs过滤/改写 →scrape(HTTP 拉/metrics,默认 15s)→metric_relabel_configs抓后改写 → 写入 TSDB。 - TSDB 存储:本地按 2 小时分块(chunk)存压缩数据(Gorilla XOR 编码,平均 1.3 字节/样本),默认保留 15 天;高基数/长期靠远程读写外推。
- Service Discovery(SD):动态发现抓取目标——K8s SD(列 Pod/Service/Node/Endpoint)、Consul SD、DNS SRV、EC2、文件(file_sd 兜底)——目标增减自动反映到抓取列表。
- relabel_configs vs metric_relabel_configs:前者抓取前改写/过滤目标(
__address__、job、instance、__meta_*);后者抓取后改写/丢弃样本(删高基数 label 如user_id)。 - 远程读写(remote_write/remote_read):把样本流式转发到远端(Thanos/Mimir/Cortex/VictoriaMetrics)——解决长期存储 + 高可用 + 全局查询,是规模化必经之路。
- 联邦集群(Federation):一个 Prometheus 拉另一个 Prometheus 的
/federate,做跨集群聚合(已被 Thanos/Mimir 的全局查询取代,新架构少用)。 - 高可用:原版 Prometheus 无内置副本去重——跑两个实例 + Alertmanager 集群(自带去重),或上 Thanos/Mimir 做存储层去重。
- 与 Grafana 集成:Grafana 用 Prometheus 作数据源,PromQL 写面板;Recording Rule 预算的指标直接被 Grafana 引用——三者构成监控闭环。
一、整体架构:采集 → 存储 → 告警 → 可视化
┌─────────────── 应用/基础设施 ───────────────┐
│ Node Exporter mysqld_exporter 应用 /metrics │
│ │ │ │ │
└───────┼──────────────┼──────────────┼─────────┘
│ │ │ 短任务 → Pushgateway(中转)
▼ ▼ ▼
┌─ Service Discovery(K8s / Consul / DNS)─────┐
│ 动态列出抓取目标(Pod IP + 端口) │
└──────────────────┬──────────────────────────┘
│ relabel_configs(抓取前过滤/改写)
▼
┌─ Prometheus Server ──────────────────────────┐
│ Scrape(HTTP 拉 /metrics,15s) │
│ metric_relabel_configs(抓后改写/丢高基数) │
│ TSDB(本地 2h 分块,默认 15 天) │
│ PromQL 引擎(面板 + 告警规则求值) │
└──┬───────────────┬───────────────┬──────────┘
│ remote_write │ Alerting Rule │ 数据源
▼ ▼ ▼
Thanos/Mimir Alertmanager Grafana
(长期/HA) (路由/分组/抑制) (大盘)每个组件职责单一、可独立替换——这是 Prometheus 的 Unix 哲学。
二、Pull 采集循环
Prometheus Server 的核心循环:
- Service Discovery 产出目标列表(
target:地址 + 元标签__meta_*)。 relabel_configs(抓取前):按规则 keep/drop 目标,或 replace 改写__address__/job/instance标签——把 K8s 元标签(__meta_kubernetes_pod_name)转成业务标签(pod)。scrape:HTTP GEThttp://target:port/metrics,带scrape_interval(默认 15s)、scrape_timeout(默认 10s)。metric_relabel_configs(抓取后):对收到的样本改写/丢弃——典型是labeldrop: user_id删高基数 label,防止时序爆炸。- 写入 TSDB:新样本追加到对应时序的当前 chunk。
yaml
scrape_configs:
- job_name: k8s-pods
kubernetes_sd_configs:
- role: pod
relabel_configs:
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
regex: "true" # 只抓带 prometheus.io/scrape: "true" 注解的 Pod
action: keep
- source_labels: [__meta_kubernetes_pod_name]
target_label: pod # 元标签 → 业务标签
metric_relabel_configs:
- regex: 'user_id|session_id' # 删高基数 label
action: labeldropup指标:每次 scrape 自动写up=1(成功)或up=0(失败)——是诊断抓取故障的第一指标(up{job="x"} == 0)。- 抓取失败常见原因:目标没暴露
/metrics、网络不通、TLS 证书问题、超时(抓取时长 > scrape_timeout)。
三、TSDB:本地时序存储
Prometheus 内置 TSDB(2017 年重写,取代老 V2 存储),设计目标:高写入吞吐 + 紧凑存储 + 快速范围查询。
- 分块(chunk):每条时序的数据按 2 小时切成一个 chunk,chunk 内用 Gorilla XOR 编码压缩 timestamp 和 value——平均 1.3 字节/样本(远小于原始 16 字节)。
- 倒排索引:metric name 和 label → 时序 ID 的倒排索引,让
http_requests_total{method="GET"}这类查询快速定位时序。 - WAL(Write-Ahead Log):写入前先记 WAL,崩溃后重放恢复——保证持久性。
- 保留期(
--storage.tsdb.retention.time):默认 15 天。超过自动删除 chunk 文件。磁盘占用 ≈ 每百万样本/天约 1-2GB(压缩后)。 - 快照/压缩:后台定期压实(compaction)——合并小 chunk、删过期数据。
本地 TSDB 的边界:单节点、无水平扩展、保留期短(15 天)。长期存储与高可用靠远程读写外推。
四、Service Discovery:动态发现目标
云原生环境目标瞬息万变(Pod 滚动更新、自动扩缩容),写死 IP 不现实。Prometheus SD 自动维护抓取列表:
| SD 类型 | 用途 | 典型场景 |
|---|---|---|
| kubernetes_sd | 列 Pod/Service/Node/Endpoint | K8s 监控事实标准 |
| consul_sd | 查 Consul 服务注册表 | 服务注册中心架构 |
| dns_sd | 解析 SRV/A 记录 | 传统 DNS 服务发现 |
| ec2_sd / azure_sd / gce_sd | 云厂商元数据 | 云主机自动发现 |
| file_sd | 读 JSON/YAML 文件 | 兜底/外部系统生成 |
| static_configs | 静态写死 | 少量固定目标 |
- K8s SD 工作方式:Prometheus 通过 in-cluster ServiceAccount 调 K8s API,列出所有 Pod(或 Service/Endpoint),每个 Pod 的元信息(name、namespace、label、annotation、IP)变成
__meta_kubernetes_pod_*标签,再由relabel_configs决定抓哪些、转成什么业务标签。 - file_sd 兜底:没有现成 SD 时,写个脚本周期性生成 targets.json,Prometheus 监听文件变化自动 reload——简单可靠。
五、relabel:抓取前后的标签工程
relabel 是 Prometheus 的「正则改写引擎」,分两个阶段:
relabel_configs(抓取前):作用于目标(target)层级。常用 action:keep/drop:按正则过滤目标(只抓带某注解的 Pod)。replace:把source_labels拼接后正则捕获,写到target_label——把__meta_kubernetes_namespace转成namespace标签。labelmap:批量重命名(如把所有__meta_kubernetes_pod_label_*转成pod_label_*)。
metric_relabel_configs(抓取后):作用于样本层级。常用action:labeldrop:删除高基数 label(user_id、request_id)——防止时序数爆炸。keep/drop:丢弃不需要的样本(如丢弃go_*runtime 指标减少存储)。
relabel 是把「基础设施标签」翻译成「业务可读标签」的关键环节,写好它面板的 sum by (namespace, service, pod) 才有意义。
六、远程读写与联邦:规模化扩展
本地 TSDB 单机边界明显,规模化靠外推:
- remote_write:把每个样本流式转发到一个远端 URL(Mimir/Thanos Receive/Cortex/VictoriaMetrics)——远端做长期存储 + 副本去重 + 全局查询。
- remote_read:查询时透明回读远端历史数据——本地只存近期,远端存长期,PromQL 无感。
- Thanos:在 Prometheus 侧加 sidecar,把 TSDB block 上传到对象存储(S3/OSS),提供 Store Gateway 全局查询 + 副本去重——保留 Prometheus 原生体验。
- Mimir(Grafana 出品):多租户、水平扩展的远端存储,metrics-as-a-service,适合大规模集中式监控。
- 联邦(Federation):一个 Prometheus 拉另一个的
/federate,做跨集群聚合——老方案,新架构多用 Thanos/Mimir 的全局查询替代。
七、与 Grafana 集成
Prometheus 不带 UI(自带的 /graph 只够调试),可视化交给 Grafana:
- 数据源配置:Grafana 添加 Prometheus 数据源(URL 指向
http://prometheus:9090),所有面板用 PromQL 查询。 - ** Recording Rule 联动**:预算的指标(
job:http_requests:rate5m)直接被 Grafana 引用——面板查询快、复用。 - 社区大盘:Grafana.com 有海量现成的 Prometheus 大盘(Node Exporter Full、K8s 集群监控等),导入 JSON 即用。
- Grafana Alerting:新版 Grafana 可直接基于 Prometheus 数据源告警(统一告警 UI),与 Alertmanager 互补。
三者构成「采集(Prometheus)→ 存储(TSDB)→ 告警(Alertmanager)→ 可视化(Grafana)」的事实标准闭环——云原生监控的默认选择。
下一步
理解了 Prometheus 全貌后,可继续看本叶参考(指标类型速查、PromQL 函数清单、易错点),或横向对比可观测性其他维度——Grafana(可视化)、ELK Stack(日志)、Jaeger(追踪)、Sentry(错误)。