前言
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 -----------|
删除旧数据
# 查看当前存储使用
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(压缩后的实际大小)
实际计算示例
# 假设:
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 |
资源配置建议
# 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 (考虑联邦分片)
控制时间序列数
# 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
# 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
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
# 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
对象存储配置
# 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
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
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
# 压缩和数据降采样
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 数据源
# 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 简化方案
单节点部署
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
remote_write:
- url: 'http://victoria-metrics:8428/api/v1/write'
queue_config:
max_samples_per_send: 5000
VMSelect + VMStorage + VMinsert(集群模式)
# 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 架构 将讲解如何构建高可用的监控系统。