【Prometheus·部署篇】存储与容量规划:本地存储、远程存储与长期保存

前言

Prometheus 默认只适合短期存储(15-30 天)。但企业往往需要保存数月甚至数年的监控数据用于趋势分析和合规审计。本篇深入 TSDB 存储机制、容量规划、远程存储方案和 Thanos 长期存储。


一、TSDB 本地存储机制

存储结构

复制代码
/data/prometheus/
├── wal/                         # Write-Ahead Log(预写日志)
│   ├── 00000001                 # WAL 段文件
│   ├── 00000002
│   └── checkpoint/              # WAL 检查点
├── 01HAB.../                    # Block(2 小时数据块)
│   ├── chunks/                  # 压缩数据块
│   │   ├── 000001
│   │   └── 000002
│   ├── index/                   # 倒排索引
│   ├── meta.json                # 元数据
│   └── tombstones               # 删除标记
├── 01HAC.../                    # 压缩合并的大 Block
├── snapshots/                   # 快照
└── lock                         # 文件锁

Block 生命周期

复制代码
Head Block(内存)          →  2小时后  →  持久化为 Block
  ↑ 最新写入                              ↓
  内存 + WAL                           压缩合并
                                          ↓
                               小 Block → 大 Block(2h → 8h → 24h → ...)

压缩合并过程

复制代码
时间轴:
  |---B1(2h)---|---B2(2h)---|---B3(2h)---|---B4(2h)---|

压缩后:
  |---------B12(4h)--------|---------B34(4h)--------|

再压缩:
  |---------------B1234(8h)----------------|

最终:
  |----------- 24h Block -----------|
  |----------- 24h Block -----------|

删除旧数据

bash 复制代码
# 查看当前存储使用
du -sh /data/prometheus/

# Prometheus 自动按 retention 删除
# --storage.tsdb.retention.time=15d    # 保存 15 天
# --storage.tsdb.retention.size=50GB   # 最大 50GB

# 手动删除特定数据(需 admin API)
# 启动时加 --web.enable-admin-api
curl -X POST http://localhost:9090/api/v1/admin/tsdb/delete_series \
  --data-urlencode 'match[]=http_requests_total{job="deprecated-app"}'

# 清理 tombstone(物理删除)
curl -X POST http://localhost:9090/api/v1/admin/tsdb/clean_tombstones

二、容量规划

计算公式

复制代码
存储大小 ≈ 时间序列数 × 每样本字节数 × 每天样本数 × 保留天数 × 压缩比

参数:
  - 时间序列数:取决于指标数量 × 标签组合数
  - 每样本字节数:~1.5 bytes(Gorilla 压缩后)
  - 每天样本数:86400 / scrape_interval
  - 压缩比:~0.1(压缩后的实际大小)

实际计算示例

python 复制代码
# 假设:
time_series_count = 100_000         # 10 万序列
sample_size = 1.5                   # bytes per sample
scrape_interval = 15                # 秒
samples_per_day = 86400 / 15        # = 5760
retention_days = 30                 # 保留 30 天

# 原始大小
raw_size = time_series_count * sample_size * samples_per_day * retention_days
# = 100,000 × 1.5 × 5760 × 30
# = 25,920,000,000 bytes = ~24 GB

# 压缩后
compressed_size = raw_size * 0.1  # 实际压缩比取决于数据
# = ~2.4 GB

# 但索引和 WAL 也要占空间
total = compressed_size * 1.5
# = ~3.6 GB

不同规模参考

时间序列数 15天保存 30天保存 90天保存
10,000 ~0.5GB ~1GB ~3GB
50,000 ~2.5GB ~5GB ~15GB
100,000 ~5GB ~10GB ~30GB
500,000 ~25GB ~50GB ~150GB
1,000,000 ~50GB ~100GB ~300GB

资源配置建议

yaml 复制代码
# Prometheus Pod 资源配置
resources:
  requests:
    cpu: 1
    memory: 2Gi
  limits:
    cpu: 4
    memory: 8Gi

# 根据序列数调整
# < 10万序列:    1 CPU, 2Gi
# 10-50万序列:   2 CPU, 4Gi
# 50-100万序列:  4 CPU, 8Gi
# > 100万序列:   8 CPU, 16Gi (考虑联邦分片)

控制时间序列数

yaml 复制代码
# 1. 降低采集频率(非关键指标)
scrape_configs:
  - job_name: 'batch-jobs'
    scrape_interval: 60s    # 1 分钟采集一次

# 2. 用 metric_relabel_configs 删除不需要的指标
scrape_configs:
  - job_name: 'mysql'
    metric_relabel_configs:
      - source_labels: [__name__]
        regex: 'go_.*|process_.*'
        action: drop    # 删除 Go runtime 和进程指标

# 3. 控制标签基数
metric_relabel_configs:
  - action: labeldrop
    regex: 'request_id|trace_id|user_id|session_id'

三、远程存储方案

Remote Write

yaml 复制代码
# prometheus.yml ------ 配置远程写入
remote_write:
  - url: 'http://thanos-receive.monitoring:19291/api/v1/receive'
    remote_timeout: 30s
    write_relabel_configs:
      # 只发送关键指标到远程
      - source_labels: [__name__]
        regex: 'up|http_requests_total|http_request_duration_seconds.*'
        action: keep
    queue_config:
      capacity: 10000           # 队列容量
      max_shards: 200            # 最大分片(并发数)
      max_samples_per_send: 2000 # 每批发送样本数
      batch_send_deadline: 5s   # 批量发送超时

Remote Read

yaml 复制代码
remote_read:
  - url: 'http://thanos-query.monitoring:9090/api/v1/query'
    read_timeout: 30s
    read_recent: false    # false = 仅查询远程历史数据,近期数据查本地

远程存储后端对比

方案 原理 优势 劣势
Thanos 对象存储 + Sidecar 架构简单,无侵入 S3 延迟高
VictoriaMetrics 自有 TSDB 高性能,低资源 自有协议
Cortex/Mimir 分布式 TSDB 高可用 部署复杂
M3DB 分布式 TSDB 高性能 运维复杂
InfluxDB 时序数据库 成熟 社区版有节点限制
Elasticsearch 全文检索+时序 多维度 资源消耗大

四、Thanos:生产推荐方案

架构

复制代码
                 ┌─────────────────────────────┐
                 │       Thanos Query          │
                 │     (查询入口,GRPC)         │
                 └──────┬──────┬──────┬───────┘
                        │      │      │
            ┌───────────┤      │      ┌───────────────┐
            │           │      │      │               │
  ┌─────────┴──┐  ┌────┴──┐  ┌┴─────┐  ┌──────────┴──┐
  │ Prometheus │  │Prom  │  │Thanos│  │   Thanos    │
  │ + Sidecar  │  │+Side │  │Store │  │   Ruler     │
  │ (集群1)    │  │(集群2)│  │(S3)  │  │ (规则计算)   │
  └─────┬──────┘  └──┬───┘  └──────┘  └──────┬──────┘
        │             │                       │
        └─────────────┴───────────────────────┘
                      ↓ Upload to S3
              ┌───────────────┐
              │  S3/MinIO     │
              │  对象存储      │
              └───────────────┘
                      ↓ Query
              ┌───────────────┐
              │   Grafana     │
              └───────────────┘

部署 Thanos Sidecar

yaml 复制代码
# Sidecar 与 Prometheus 一起部署
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  template:
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:v2.50.0
          args:
            - "--config.file=/etc/prometheus/prometheus.yml"
            - "--storage.tsdb.path=/prometheus"
            - "--storage.tsdb.retention.time=15d"  # 本地短期
          volumeMounts:
            - name: data
              mountPath: /prometheus

        - 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.yaml"
          volumeMounts:
            - name: data
              mountPath: /prometheus
              readOnly: true
            - name: thanos-config
              mountPath: /etc/thanos
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: prometheus-data
        - name: thanos-config
          configMap:
            name: thanos-objstore

对象存储配置

yaml 复制代码
# S3 配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: thanos-objstore
  namespace: monitoring
data:
  objstore.yaml: |
    type: S3
    config:
      bucket: "thanos-metrics"
      endpoint: "s3.us-east-1.amazonaws.com"
      region: "us-east-1"
      access_key: "AKIA..."
      secret_key: "..."
      insecure: false

Thanos Query

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thanos-query
  namespace: monitoring
spec:
  template:
    spec:
      containers:
        - name: thanos-query
          image: thanosio/thanos:v0.35.0
          args:
            - "query"
            - "--grpc-address=0.0.0.0:10901"
            - "--http-address=0.0.0.0:9090"
            - "--query.replica-label=prometheus_replica"
            - "--store=thanos-sidecar.monitoring:10901"
            - "--store=thanos-store.monitoring:10901"
            - "--store=thanos-ruler.monitoring:10901"
          ports:
            - name: grpc
              containerPort: 10901
            - name: http
              containerPort: 9090

Thanos Store Gateway

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thanos-store
  namespace: monitoring
spec:
  template:
    spec:
      containers:
        - name: thanos-store
          image: thanosio/thanos:v0.35.0
          args:
            - "store"
            - "--data-dir=/data"
            - "--objstore.config-file=/etc/thanos/objstore.yaml"
            - "--grpc-address=0.0.0.0:10901"
          volumeMounts:
            - name: data
              mountPath: /data
            - name: thanos-config
              mountPath: /etc/thanos
          resources:
            requests:
              memory: 4Gi
            limits:
              memory: 8Gi

Thanos Compactor

yaml 复制代码
# 压缩和数据降采样
apiVersion: apps/v1
kind: Deployment
metadata:
  name: thanos-compactor
  namespace: monitoring
spec:
  template:
    spec:
      containers:
        - name: thanos-compactor
          image: thanosio/thanos:v0.35.0
          args:
            - "compact"
            - "--data-dir=/data"
            - "--objstore.config-file=/etc/thanos/objstore.yaml"
            - "--retention.resolution-raw=30d"        # 原始数据保留30天
            - "--retention.resolution-5m=180d"        # 5分钟降采样保留180天
            - "--retention.resolution-1h=365d"        # 1小时降采样保留1年
          volumeMounts:
            - name: data
              mountPath: /data

Grafana 配置 Thanos 数据源

yaml 复制代码
# Grafana 数据源指向 Thanos Query
apiVersion: 1
datasources:
  - name: Thanos
    type: prometheus
    access: proxy
    url: http://thanos-query.monitoring:9090
    isDefault: true
    jsonData:
      timeInterval: 15s

五、数据降采样

复制代码
原始数据(15s 间隔)→ 保留 30 天
      ↓ Compactor 降采样
5 分钟降采样 → 保留 180 天(用于月度趋势)
      ↓ 再降采样
1 小时降采样 → 保留 365 天(用于年度趋势)

查询时的自动选择:
  查询最近 30 天   → 用原始数据(15s 精度)
  查询 30-180 天  → 用 5m 降采样
  查询 180-365 天 → 用 1h 降采样

六、VictoriaMetrics 简化方案

单节点部署

bash 复制代码
docker run -d \
  --name victoria-metrics \
  -p 8428:8428 \
  -v /data/vm:/storage \
  victoriametrics/victoria-metrics:v1.100.0 \
  -retentionPeriod=365d \
  -storageDataPath=/storage

Prometheus Remote Write

yaml 复制代码
remote_write:
  - url: 'http://victoria-metrics:8428/api/v1/write'
    queue_config:
      max_samples_per_send: 5000

VMSelect + VMStorage + VMinsert(集群模式)

yaml 复制代码
# docker-compose 集群部署
services:
  vminsert:
    image: victoriametrics/victoria-metrics:v1.100.0-cluster
    command:
      - '--storageNode=vmstorage:8401'
    ports:
      - "8480:8480"

  vmselect:
    image: victoriametrics/victoria-metrics:v1.100.0-cluster
    command:
      - '--storageNode=vmstorage:8401'
    ports:
      - "8481:8481"

  vmstorage:
    image: victoriametrics/victoria-metrics:v1.100.0-cluster
    command:
      - '--retentionPeriod=365d'
    volumes:
      - vm-data:/storage
    ports:
      - "8400:8400"
      - "8401:8401"

要点回顾

方案 适用场景 保留时长 复杂度
本地 TSDB 小规模 15-30天
Thanos 生产大规模 1年+
VictoriaMetrics 追求简单高效 1年+
Cortex/Mimir 超大规模 1年+
  • TSDB Block 从 2h 合并到更大,最终自动删除过期数据
  • 容量 = 时间序列数 × 样本大小 × 保留天数
  • 用 metric_relabel_configs 删除不需要的指标控制基数
  • Thanos = Prometheus + Sidecar + S3 + Query + Compactor
  • 降采样让长期数据占更少空间

下一篇预告

存储和容量搞定后,下一篇 【Prometheus·部署篇】高可用方案:联邦集群与 Thanos 架构 将讲解如何构建高可用的监控系统。

相关推荐
heimeiyingwang2 小时前
【Prometheus·可视化篇】Grafana 集成:数据源配置与 Dashboard 设计原则
grafana·prometheus
IT界的老黄牛2 小时前
Jenkins 构建卡了 23 天,abort 按钮点了没用
jenkins·maven·prometheus·告警·排查·ci-cd
heimeiyingwang2 天前
【Prometheus·告警篇】告警规则:Recording Rules 与 Alerting Rules 最佳实践
prometheus
AAA@峥3 天前
从零搭建 Prometheus 完整监控告警体系|Linux 部署 + node_exporter+Grafana 可视化
云原生·grafana·prometheus
liuyicenysabel5 天前
Grafana + Prometheus 分级告警配置设计(P0/P1/P2)
javascript·grafana·prometheus
随遇而安zx5 天前
SpringCloud---可观测性与监控:Actuator / Micrometer / Prometheus / Grafana 深度解析
spring cloud·grafana·prometheus
qq_452396235 天前
第四篇:《Prometheus 深度实战:指标设计、Exporter 开发与服务发现》
服务发现·prometheus
刘某的Cloud5 天前
k8s部署prometheus架构规则
linux·运维·kubernetes·prometheus·监控
LlmCraft|大模型工程实践5 天前
12. Docker 日志管理与监控:ELK 日志收集 + Prometheus 性能监控
elk·docker·prometheus