概述

Prometheus 默认是单节点架构,这在生产环境中是一个危险的隐患。一个 Prometheus 实例挂掉意味着整个监控体系失明——你无法在故障期间看到任何指标,告警也会因为规则不评估而完全失效。当数据量增长到单机存储和处理能力的极限时,还会面临写入超时、查询缓慢、磁盘爆满等问题。

本文系统性地分析 Prometheus 高可用和水平扩展方案,从最简单的双副本到 Thanos、Mimir、VictoriaMetrics、Cortex 等远程存储方案,帮助你根据实际场景做出正确的技术选型。

参考来源:Prometheus 官方文档 — HAThanos 官方文档

一、单点问题分析

1.1 单点 Prometheus 的风险

┌──────────────┐     ┌───────────────┐     ┌──────────┐
│  Exporters   │ ──→ │  Prometheus   │ ──→ │  Grafana │
│  (targets)   │     │  (单节点)      │     │  Alertmgr│
└──────────────┘     └───────────────┘     └──────────┘
                     ┌──────┴──────┐
                     │  本地 TSDB   │
                     │  (15-30 天)  │
                     └─────────────┘

这个架构的脆弱点:

风险点影响发生概率
Prometheus 进程崩溃监控完全中断,告警失效
宿主机宕机同上,且可能丢失最近数据
磁盘故障历史数据丢失低-中
磁盘空间耗尽写入失败,数据丢失中-高
单机内存/CPU 不足写入延迟、查询超时高(数据量增长后)
网络分区部分 target 无法采集

1.2 单机性能瓶颈

Prometheus 的性能受以下因素制约:

  • 时间序列数量:每百万条活跃时间序列约占 1-2 GB 内存
  • 采集速率:单机推荐每秒处理不超过 100 万采样点
  • 查询复杂度:大范围 PromQL 查询可能导致 OOM
  • 本地存储:TSDB 默认保留 15 天,长时间保留需要大量磁盘
# 检查 Prometheus 活跃时间序列数量
curl -s http://localhost:9090/api/v1/status/tsdb | jq '.data.seriesCountByMetricName | length'

# 检查写入速率
curl -s http://localhost:9090/api/v1/status/tsdb | jq '.data.headStats'

当单实例的活跃时间序列超过 200 万或写入速率超过 80 万/秒时,就该考虑水平扩展了。

二、双副本方案

2.1 双副本架构

最直接的高可用方案是部署两个完全相同的 Prometheus 实例,采集相同的目标:

┌──────────────┐
│  Exporters   │
└──────┬───────┘
   ┌───┴───┐
   ▼       ▼
┌─────────┐ ┌─────────┐
│  Prom-A │ │  Prom-B │
│ (副本1) │ │ (副本2) │
└────┬────┘ └────┬────┘
     │           │
     ▼           ▼
┌──────────────────────┐
│   Alertmanager HA    │
│   (Gossip 去重)      │
└──────────────────────┘

两个 Prometheus 实例独立采集和评估告警规则,都向 Alertmanager 发送告警。Alertmanager 通过 Gossip 协议在实例间去重,确保同一告警只发送一次通知。

2.2 Alertmanager HA 配置

# Alertmanager 集群配置
alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - 'alertmanager-1:9093'
            - 'alertmanager-2:9093'
            - 'alertmanager-3:9093'

Alertmanager 启动时通过 --cluster.peer 参数组成集群:

# alertmanager-1
alertmanager \
  --config.file=/etc/alertmanager/config.yml \
  --storage.path=/data/alertmanager \
  --cluster.listen-address=0.0.0.0:9094 \
  --cluster.peer=alertmanager-2:9094 \
  --cluster.peer=alertmanager-3:9094

# alertmanager-2
alertmanager \
  --config.file=/etc/alertmanager/config.yml \
  --storage.path=/data/alertmanager \
  --cluster.listen-address=0.0.0.0:9094 \
  --cluster.peer=alertmanager-1:9094 \
  --cluster.peer=alertmanager-3:9094

2.3 双副本的局限

双副本解决了单点故障问题,但有以下局限:

  • 存储翻倍:两个实例各自存储完整数据,存储成本翻倍
  • 查询需外部去重:Grafana 查询时需要指定数据源,两个实例的数据有微小差异(采集时间点不完全一致)
  • 无法水平扩展:单实例的采集和处理能力上限没有改变
  • 无长期存储:仍然依赖本地 TSDB,无法保留超过 30 天的历史数据

双副本方案适合中小规模(活跃时间序列 < 100 万)的监控需求,是成本最低的高可用方案。

三、远程存储方案概述

当单机性能或存储容量成为瓶颈时,需要引入远程存储。Prometheus 原生支持 remote_write 和 remote_read 接口,可以将数据流式传输到外部存储系统。

┌─────────────────────────────────────────────────────┐
│                    各集群 Prometheus                   │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐              │
│  │  Prom-1 │  │  Prom-2 │  │  Prom-3 │              │
│  └────┬────┘  └────┬────┘  └────┬────┘              │
│       │            │            │                     │
│       └────────────┼────────────┘                     │
│                    │ remote_write                     │
└────────────────────┼─────────────────────────────────┘
          ┌──────────────────────┐
          │    远程存储后端         │
          │  (Thanos/Mimir/VM)  │
          └──────────┬───────────┘
          ┌──────────┴───────────┐
          │   全局查询 / 长期存储    │
          │   (PromQL 兼容)       │
          └──────────────────────┘

主流远程存储方案对比:

方案开发者核心特性对象存储多租户成熟度
ThanosImprobableSidecar + 对象存储 + 全局查询支持不支持
MimirGrafana LabsCortex 重写版,水平扩展强支持支持
VictoriaMetricsVictoriaMetrics自研存储引擎,性能极高支持支持(企业版)
CortexGrafana LabsMimir 前身,多租户支持支持维护模式
InfluxDBInfluxData时序数据库,非 Prom 生态不支持支持

四、Thanos:最流行的远程存储方案

4.1 Thanos 架构

┌──────────────────────────────────────────────────────────┐
│                     Thanos 架构                            │
│                                                          │
│  ┌─────────┐    ┌──────────────┐    ┌──────────────┐    │
│  │ Prom +  │    │  Thanos      │    │  Thanos      │    │
│  │ Sidecar │    │  Store       │    │  Compactor   │    │
│  │ (上传)  │    │  (读历史数据) │    │  (降采样)     │    │
│  └────┬────┘    └──────┬───────┘    └──────┬───────┘    │
│       │                │                   │            │
│       ▼                │                   ▼            │
│  ┌─────────────────────┴───────────────────┐            │
│  │           对象存储 (S3/GCS/MinIO)        │            │
│  └─────────────────────┬───────────────────┘            │
│                        │                                │
│  ┌─────────────────────┴───────────────┐                │
│  │           Thanos Query              │                │
│  │     (全局 PromQL 查询入口)            │                │
│  └─────────────────────┬───────────────┘                │
│                        │                                │
│  ┌─────────────────────┴───────────────┐                │
│  │           Thanos Query Frontend      │                │
│  │     (查询缓存 / 分片 / 限流)          │                │
│  └─────────────────────────────────────┘                │
└──────────────────────────────────────────────────────────┘

Thanos 的核心组件:

组件作用
Sidecar部署在 Prometheus 旁,将 TSDB 块上传到对象存储
Store从对象存储读取历史数据,响应 Query 请求
Compactor对对象存储中的数据进行降采样和压缩
Query接收 PromQL 查询,从多个数据源(Sidecar/Store/Ruler)获取结果
Query Frontend查询缓存、分片、限流
Ruler独立评估告警规则(不依赖 Prometheus 实例)
Receiver接收 remote_write 数据(可选,支持写入路径高可用)

4.2 Sidecar 模式部署

# Prometheus + Thanos Sidecar (K8s Deployment)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
spec:
  replicas: 1
  template:
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:v2.52.0
          args:
            - '--config.file=/etc/prometheus/prometheus.yml'
            - '--storage.tsdb.path=/prometheus'
            - '--storage.tsdb.retention.time=24h'  # 本地只保留 24h,历史数据上传到对象存储
            - '--storage.tsdb.min-block-duration=2h'
            - '--storage.tsdb.max-block-duration=2h'
            - '--web.enable-lifecycle'
          ports:
            - containerPort: 9090

        - name: thanos-sidecar
          image: thanosio/thanos:v0.35.0
          args:
            - sidecar
            - --tsdb.path=/prometheus
            - --prometheus.url=http://localhost:9090
            - --objstore.config-file=/etc/thanos/objstore.yml
            - --shipper.upload-compacted
          volumeMounts:
            - name: prometheus-data
              mountPath: /prometheus

对象存储配置(以 S3 为例):

# objstore.yml
type: S3
config:
  bucket: thanos-storage
  endpoint: s3.us-east-1.amazonaws.com
  region: us-east-1
  access_key: AKIAIOSFODNN7EXAMPLE
  secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  insecure: false

4.3 全局查询

Thanos Query 对接 Grafana,提供跨集群全局查询能力:

# Thanos Query 部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thanos-query
spec:
  template:
    spec:
      containers:
        - name: query
          image: thanosio/thanos:v0.35.0
          args:
            - query
            - --http-address=0.0.0.0:9090
            - --grpc-address=0.0.0.0:10901
            - --store=thanos-sidecar-cluster-a:10901  # 集群 A 的实时数据
            - --store=thanos-sidecar-cluster-b:10901  # 集群 B 的实时数据
            - --store=thanos-store:10901              # 对象存储中的历史数据
            - --query.replica-label=replica           # 去重标签
          ports:
            - containerPort: 9090

通过 --query.replica-label=replica,Thanos Query 会自动对双副本 Prometheus 的重复数据进行去重,查询时返回一致性结果。

4.4 Thanos 的优势与局限

优势

  • 无侵入式接入,Prometheus 配置改动最小
  • 全局查询,跨集群统一视图
  • 对象存储成本低(S3 约 $0.023/GB/月)
  • 支持降采样(5m → 1h → 精度递减),长周期查询性能好
  • 社区活跃,生产案例多

局限

  • Sidecar 模式依赖 Prometheus 本地 TSDB 的 2 小时 block 机制,数据上传有延迟
  • 不原生支持水平扩展写入(需 Receiver + ingestion blocks)
  • 组件较多,运维复杂度中等
  • 不支持多租户

五、Mimir:Grafana Labs 的新一代方案

5.1 Mimir 架构

Mimir 是 Grafana Labs 对 Cortex 的重写版本,采用微服务架构,原生支持水平扩展和多租户。

┌──────────────────────────────────────────────────┐
│                    Mimir 架构                      │
│                                                  │
│  Prom ──remote_write──→ ┌──────────────┐        │
│                          │  Distributor │        │
│                          └──────┬───────┘        │
│                                 │                 │
│                          ┌──────┴───────┐        │
│                          │   Ingester   │        │
│                          │ (内存写入层)  │        │
│                          └──────┬───────┘        │
│                                 │                 │
│                          ┌──────┴───────┐        │
│                          │  Store-gw    │        │
│                          │ (历史数据读)  │        │
│                          └──────┬───────┘        │
│                                 │                 │
│                          ┌──────┴───────┐        │
│                          │   Querier    │        │
│                          │ (PromQL 查询) │        │
│                          └──────────────┘        │
│                                                  │
│  对象存储 (S3) ←── 块存储 / 索引 / 元数据 ──→     │
│                                                  │
│  Consul/Memberlist ←── 服务发现 ──→               │
└──────────────────────────────────────────────────┘

5.2 Prometheus remote_write 配置

# prometheus.yml
remote_write:
  - url: http://mimir-distributor:8080/api/v1/push
    headers:
      X-Scope-OrgID: tenant-1  # 多租户 ID
    write_relabel_configs:
      - source_labels: [__name__]
        regex: 'go_(gc|memstats)_.+'
        action: drop  # 丢弃不需要的指标,减少写入量
    queue_config:
      capacity: 10000
      max_samples_per_send: 2000
      batch_send_deadline: 5s
      min_backoff: 30ms
      max_backoff: 100ms

5.3 Mimir vs Thanos

维度ThanosMimir
写入路径Sidecar 被动上传(2h block)remote_write 主动推送(实时)
写入延迟2 小时(block 完成)秒级
水平扩展有限(Receiver 可扩展但有瓶颈)原生水平扩展
多租户不支持原生支持
查询性能中等高(有查询缓存和分片)
组件复杂度
对象存储S3/GCS/Azure/MinIOS3/GCS/Azure/MinIO
告警评估Ruler 组件Ruler 组件
压缩/降采样CompactorCompactor
社区活跃度

选型建议:单集群或少量集群优先考虑 Thanos,简单且足够。多租户、大规模(活跃时间序列 > 1000 万)或需要毫秒级写入延迟时选择 Mimir。

六、VictoriaMetrics:高性能自研存储

6.1 架构特点

VictoriaMetrics(VM)使用自研的列式存储引擎,在写入吞吐和查询性能上显著优于基于 TSDB 的方案。

┌──────────────────────────────────────────────────────┐
│              VictoriaMetrics 架构                     │
│                                                      │
│  Prom ──remote_write──→ ┌──────────────────┐         │
│                          │  vminsert         │         │
│                          │  (写入入口,LB)    │         │
│                          └────────┬──────────┘         │
│                                   │                    │
│                          ┌────────┴──────────┐        │
│                          │  vmstorage (×N)    │        │
│                          │  (数据分片存储)     │        │
│                          └────────┬──────────┘        │
│                                   │                    │
│                          ┌────────┴──────────┐        │
│                          │  vmselect         │        │
│                          │  (查询入口,合并)   │        │
│                          └───────────────────┘        │
└──────────────────────────────────────────────────────┘

6.2 集群模式部署

# 单节点模式(快速体验)
./victoria-metrics \
  -storageDataPath=/data \
  -retentionPeriod=12 \
  -httpListenAddr=:8428

# 集群模式(生产环境)
# vmstorage 节点(数据存储,3 个节点)
./vmstorage \
  -storageDataPath=/data \
  -retentionPeriod=12 \
  -httpListenAddr=:8482

# vminsert 节点(写入入口)
./vminsert \
  -httpListenAddr=:8480 \
  -storageNode=vmstorage-1:8400,vmstorage-2:8400,vmstorage-3:8400

# vmselect 节点(查询入口)
./vmselect \
  -httpListenAddr=:8481 \
  -storageNode=vmstorage-1:8400,vmstorage-2:8400,vmstorage-3:8400

6.3 VictoriaMetrics 优势

优势说明
极致性能列式压缩 + 内存映射,写入吞吐比 Prometheus 高 3-5 倍
低存储成本压缩率比 Prometheus 高 5-10 倍
PromQL + MetricsQL兼容 PromQL,额外提供 MetricsQL 扩展函数
原生高可用集群模式原生支持副本和分片
单二进制部署单节点模式只有一个二进制文件,部署极简
内置降采样自动对不同时间范围的数据做降采样
成本低开源版免费,企业版支持多租户和告警

6.4 vmagent:轻量级采集代理

VM 还提供 vmagent,可替代 Prometheus 做采集,支持更多服务发现方式和远程写入:

./vmagent \
  -promscrape.config=/etc/vmagent/prometheus.yml \
  -remoteWrite.url=http://vminsert:8480/insert/0/prometheus/api/v1/write \
  -remoteWrite.url=http://backup-vminsert:8480/insert/0/prometheus/api/v1/write \
  -remoteWrite.multitenantURL=http://vminsert:8480/insert/multitenant/prometheus/api/v1/write

vmagent 支持同时写入多个远程存储(多活写入),写入失败自动重试,是替代 Prometheus 采集层的轻量方案。

七、联邦集群

7.1 联邦架构

联邦是 Prometheus 原生提供的高可用和聚合查询方案,通过 /federate 端点从一个 Prometheus 拉取另一个 Prometheus 的指标。

┌─── 区域 A ──────────┐    ┌─── 区域 B ──────────┐
│  Prometheus-A       │    │  Prometheus-B       │
│  (采集 A 区域 targets)│    │  (采集 B 区域 targets)│
└────────┬────────────┘    └────────┬────────────┘
         │                          │
         │   scrape /federate       │
         │ ←────────────────────────│
         ▼                          ▼
┌──────────────────────────────────────────────┐
│           全局 Prometheus (联邦)               │
│  (聚合查询,跨区域视图)                        │
└──────────────────┬───────────────────────────┘
              ┌──────────┐
              │  Grafana  │
              └──────────┘

7.2 联邦配置

# 全局 Prometheus
scrape_configs:
  - job_name: 'federate'
    scrape_interval: 30s
    honor_labels: true
    metrics_path: '/federate'
    params:
      'match[]':
        - '{job="node"}'
        - '{job="mysql"}'
        - '{__name__=~"up|prometheus_.*|alertmanager_.*"}'
        - '{alertname!=""}'  # 告警指标
    static_configs:
      - targets:
          - 'prometheus-region-a:9090'
          - 'prometheus-region-b:9090'
    relabel_configs:
      - source_labels: [__address__]
        regex: 'prometheus-(.+):9090'
        target_label: source_prometheus
        replacement: '${1}'

match[] 参数控制联邦拉取的指标范围。honor_labels: true 确保原始标签不被覆盖。

7.3 联邦的局限

  • 查询压力传递:联邦查询会在子 Prometheus 上执行,大量联邦请求会增加子节点负载
  • 级联延迟:数据从子 Prometheus → 联邦 Prometheus,存在 1-2 个采集周期的延迟
  • 不支持跨 Prometheus 查询聚合sum(rate(metric[5m])) 会在每个子 Prometheus 上分别计算再聚合,结果可能不准确
  • 无长期存储:联邦不解决存储扩展问题

结论:联邦适合小规模集群的简单聚合查询。如果需要跨集群精确聚合查询或长期存储,应使用 Thanos/Mimir/VictoriaMetrics。

八、Cortex 架构(了解)

Cortex 是 Grafana Labs 的早期方案,现已逐步被 Mimir 取代。了解其架构有助于理解 Mimir 的设计。

Cortex 与 Mimir 的关系:

维度CortexMimir
状态维护模式积极开发
架构微服务微服务(优化)
存储引擎基于 chunks基于 blocks(兼容 Prometheus TSDB)
兼容性PromQL 部分完全兼容 PromQL
性能高(2-5x Cortex)
迁移可迁移到 Mimir

新项目不建议选择 Cortex,直接使用 Mimir。

九、方案选型对比

9.1 综合对比矩阵

维度双副本联邦ThanosMimirVictoriaMetrics
高可用✓✓✓✓✓✓✓
长期存储✓✓✓✓✓✓✓
水平扩展✓✓✓✓✓✓
多租户✓✓✓(企业版)
全局查询✓✓✓✓✓✓✓
部署复杂度低-中
存储成本低(对象存储)低(对象存储)极低
查询性能中-高极高
运维复杂度低-中

9.2 选型决策框架

活跃时间序列 < 50 万?
  ├── 是 → 双副本 + Alertmanager HA(最简方案)
  └── 否 → 活跃时间序列 < 200 万?
              ├── 是 → 单集群 Thanos Sidecar(对象存储 + 全局查询)
              └── 否 → 需要多租户?
                          ├── 是 → Mimir(原生多租户 + 水平扩展)
                          └── 否 → 追求极致性能?
                                      ├── 是 → VictoriaMetrics 集群
                                      └── 否 → Thanos Receiver 或 Mimir

9.3 按场景推荐

场景推荐方案理由
初创团队 / 小规模双副本成本最低,运维简单
单 K8s 集群Thanos Sidecar无侵入接入,社区成熟
多 K8s 集群Thanos / VM全局查询 + 对象存储
SaaS 平台Mimir原生多租户 + 水平扩展
大规模 / 追求性能VictoriaMetrics存储压缩率最高,查询性能最强
需要可视化告警一体化Thanos / Mimir + GrafanaGrafana 生态深度集成

十、生产实践建议

10.1 数据分层保留

# Thanos Compactor 降采样配置
# 原始数据保留 30 天,5m 降采样保留 90 天,1h 降采样保留 1 年
compaction:
  retention_resolution_raw: 30d
  retention_resolution_5m: 90d
  retention_resolution_1h: 365d

10.2 remote_write 调优

remote_write:
  - url: 'http://thanos-receive:19291/api/v1/receive'
    queue_config:
      capacity: 10000              # 队列容量
      max_samples_per_send: 2000   # 每批发送采样数
      batch_send_deadline: 5s      # 批量发送超时
      min_backoff: 30ms            # 最小重试间隔
      max_backoff: 100ms           # 最大重试间隔
    remote_timeout: 30s
    write_relabel_configs:
      # 丢弃不需要的指标
      - source_labels: [__name__]
        regex: 'go_(gc|memstats|threads)_.+'
        action: drop
      - source_labels: [__name__]
        regex: 'prometheus_.+'
        action: drop

10.3 监控你的监控

别忘了监控 Prometheus 自身和远程存储:

# 监控 Thanos 组件
scrape_configs:
  - job_name: 'thanos-sidecar'
    static_configs:
      - targets: ['thanos-sidecar:10902']
  - job_name: 'thanos-query'
    static_configs:
      - targets: ['thanos-query:10902']

# 关键告警规则
groups:
  - name: prometheus-ha
    rules:
      - alert: PrometheusRemoteWriteFailures
        expr: rate(prometheus_remote_storage_failed_samples_total[5m]) > 0
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Prometheus remote write 失败"
          description: "实例 {{ $labels.instance }} remote write 失败率 > 0"

      - alert: ThanosSidecarUploadFailing
        expr: rate(thanos_sidecar_bucket_uploads_failures_total[5m]) > 0
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "Thanos Sidecar 上传失败"

总结

Prometheus 高可用和水平扩展是一个渐进式选择,没有一劳永逸的方案。核心决策路径:

  • 规模判断先行:先评估活跃时间序列数量、写入速率和存储保留需求,再决定方案
  • 双副本是底线:无论什么规模,双副本 Prometheus + Alertmanager HA 是高可用的基本保障
  • Thanos 适合多集群:无侵入式 Sidecar 模式,对象存储成本低,社区成熟,是多集群场景的首选
  • Mimir 适合大规模多租户:原生水平扩展和多租户,适合 SaaS 平台和超大规模监控
  • VictoriaMetrics 追求性能:存储压缩率和查询性能最优,适合对成本和性能敏感的场景
  • 联邦方案仅适合小规模:简单但局限大,大规模场景应迁移到 Thanos 或 VM

记住:监控系统的可用性决定了你的运维上限。一个不可靠的监控系统,比没有监控更危险——因为它给你虚假的安全感。

参考资料与致谢

本文在撰写过程中参考了以下资料,感谢原作者的贡献:

  1. Prometheus 官方文档 — HA — Prometheus 官方,参考了Prometheus 官方文档 — HA相关内容
  2. Thanos 官方文档 — Thanos 项目,参考了Thanos 官方文档相关内容