Skip to content

架构与服务发现: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__jobinstance__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 的核心循环:

  1. Service Discovery 产出目标列表(target:地址 + 元标签 __meta_*)。
  2. relabel_configs(抓取前):按规则 keep/drop 目标,或 replace 改写 __address__/job/instance 标签——把 K8s 元标签(__meta_kubernetes_pod_name)转成业务标签(pod)。
  3. scrape:HTTP GET http://target:port/metrics,带 scrape_interval(默认 15s)、scrape_timeout(默认 10s)。
  4. metric_relabel_configs(抓取后):对收到的样本改写/丢弃——典型是 labeldrop: user_id 删高基数 label,防止时序爆炸。
  5. 写入 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: labeldrop
  • up 指标:每次 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/EndpointK8s 监控事实标准
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_idrequest_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(错误)。