概述
Prometheus 是云原生监控领域的事实标准,但它在长期数据存储和全局查询方面存在明显短板:本地存储默认只保留 15 天数据,单实例无法跨集群聚合查询,高可用方案也相对复杂。Thanos 作为 CNCF 孵化项目,通过将 Prometheus 数据上传到对象存储(如 S3、GCS、MinIO)实现了无限容量的长期存储,并通过分布式查询组件提供跨集群的全局视图。
将深入剖析 Thanos 的架构设计,并结合生产环境实战经验,详细讲解各组件的配置、部署和运维要点。
Thanos 解决了什么问题
在引入 Thanos 之前,我们首先需要理解 Prometheus 原生存储的局限性:
| 维度 | Prometheus 原生 | Thanos 增强 |
|---|---|---|
| 数据保留 | 默认 15 天,受本地磁盘限制 | 理论无限,依赖对象存储容量 |
| 高可用 | 需要 Thanos Sidecar 或 remote_write 双写 | Sidecar + Query 天然支持 |
| 全局查询 | 联邦方案,有限且易丢数据 | Query 组件聚合所有 Store API |
| 降采样 | 不支持 | Compactor 自动降采样,优化长周期查询 |
| 历史数据查询 | 超出保留期即丢失 | 可查询数月甚至数年前数据 |
| 跨集群视图 | 需要额外联邦配置 | 原生支持多集群统一查询 |
核心思路是:不改 Prometheus 本身,通过 Sidecar 旁路将数据上传到对象存储,再通过 Query 组件统一查询。这种设计保持了 Prometheus 的简单性,同时获得了企业级存储和查询能力。
核心架构与组件
整体架构
Thanos 的架构围绕"Sidecar 上传、Store 读取、Query 聚合"三个核心环节展开:
┌─────────────────────────────────────────────────────────┐
│ 对象存储 (S3/MinIO/GCS) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Block 1 │ │ Block 2 │ │ Block N │ │
│ │ (2h raw) │ │ (5m down)│ │ (1h down)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ ▲ ▲ │
│ │ │ │
│ ┌─────┴───────┐ ┌──────┴──────┐ │
│ │ Sidecar │ │ Store │ │
│ │ (上传Block) │ │ (读取Block) │ │
│ └─────┬───────┘ └──────┬──────┘ │
│ │ │ │
│ ┌─────┴───────┐ ┌──────┴──────┐ │
│ │ Prometheus │ │ Compactor │ │
│ │ (本地TSDB) │ │ (压缩+降采样)│ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
│ └──────────┐ ┌──────────────────┘ │
│ ▼ ▼ │
│ ┌──────────────┐ │
│ │ Query │ ◄── Grafana / PromQL │
│ │ (全局查询) │ │
│ └──────┬───────┘ │
│ │ │
│ ┌──────┴───────┐ │
│ │ Ruler │ ──► Alertmanager │
│ │ (全局告警评估) │ │
│ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
组件职责
| 组件 | 职责 | 部署方式 |
|---|---|---|
| Sidecar | 与 Prometheus 同 Pod 部署,将 TSDB Block 上传到对象存储,同时暴露 Store API | DaemonSet/Sidecar |
| Query | 聚合多个 Store API 后端的数据,执行 PromQL 查询,去重处理 | Deployment(多副本 HA) |
| Store Gateway | 从对象存储读取 Block 数据,暴露 Store API 给 Query | Deployment(多副本 HA) |
| Compactor | 压缩和降采样 Block 数据,执行保留策略 | 单实例(StatefulSet) |
| Ruler | 评估告警规则,将告警发送给 Alertmanager | Deployment(多副本 HA) |
| Receiver | 通过 remote_write 接收 Prometheus 数据(可选,适用于 Sidecar 不便的场景) | StatefulSet |
参考 Thanos 官方架构文档 了解完整设计理念。
生产部署实践
前置准备:对象存储配置
以 MinIO(S3 兼容)为例,先准备 bucket 和访问凭证:
# 使用 mc 客户端创建 bucket
mc alias set thanos-minio http://minio:9000 thanos-admin thanos-password
mc mb thanos-minio/thanos-data
mc admin policy set thanos-minio readwrite user=thanos-admin
Thanos 对象存储配置文件 objstore.yml:
type: S3
config:
bucket: thanos-data
endpoint: minio:9000
region: ""
access_key: thanos-admin
secret_key: thanos-password
insecure: true
http_config:
idle_conn_timeout: 90s
response_header_timeout: 15s
insecure_skip_verify: false
trace:
enable: false
list_objects_version: "v2"
生产建议:access_key 和 secret_key 应通过 Kubernetes Secret 注入,不要明文写在 ConfigMap 中。上面示例仅用于演示。
Sidecar 部署
Sidecar 与 Prometheus 在同一 Pod 中运行,需要满足两个条件:
- Prometheus 启动时必须带
--storage.tsdb.min-block-duration=2h和--storage.tsdb.max-block-duration=2h参数 - Sidecar 需要
objstore.yml配置来上传数据
# prometheus-with-thanos-sidecar.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: thanos-objstore-config
labels:
app.kubernetes.io/name: thanos
data:
objstore.yml: |
type: S3
config:
bucket: thanos-data
endpoint: minio:9000
access_key: thanos-admin
secret_key: thanos-password
insecure: true
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: prometheus
labels:
app.kubernetes.io/name: prometheus
spec:
serviceName: prometheus
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: prometheus
template:
metadata:
labels:
app.kubernetes.io/name: prometheus
thanos-store: "true"
spec:
serviceAccountName: prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.55.0
args:
- "--config.file=/etc/prometheus/prometheus.yml"
- "--storage.tsdb.path=/data"
- "--storage.tsdb.retention.time=6h"
- "--storage.tsdb.min-block-duration=2h"
- "--storage.tsdb.max-block-duration=2h"
- "--web.enable-lifecycle"
- "--web.enable-admin-api"
ports:
- containerPort: 9090
name: web
volumeMounts:
- name: config
mountPath: /etc/prometheus
- name: data
mountPath: /data
- name: thanos-sidecar
image: thanosio/thanos:v0.37.0
args:
- "sidecar"
- "--tsdb.path=/data"
- "--prometheus.url=http://localhost:9090"
- "--objstore.config-file=/etc/thanos/objstore.yml"
- "--shipper.upload-compacted"
- "--reloader.config-file=/etc/prometheus/prometheus.yml"
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 10902
name: grpc
- containerPort: 10901
name: http
volumeMounts:
- name: data
mountPath: /data
- name: thanos-config
mountPath: /etc/thanos
volumes:
- name: config
configMap:
name: prometheus-config
- name: thanos-config
configMap:
name: thanos-objstore-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
关键参数说明:
--storage.tsdb.retention.time=6h:本地只保留 6 小时数据,历史数据上传到对象存储后本地可清理--storage.tsdb.min-block-duration=2h和--max-block-duration=2h:确保 Block 大小固定为 2 小时,这是 Thanos 上传的前提--shipper.upload-compacted:允许上传已压缩的 Block--web.enable-admin-api:Sidecar 需要调用 Prometheus Admin API 来获取 Block 信息
Query 组件部署
Query 是 Thanos 的查询入口,负责从多个后端 Store API 收集数据并执行 PromQL:
# thanos-query.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-query
labels:
app.kubernetes.io/name: thanos-query
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: thanos-query
template:
metadata:
labels:
app.kubernetes.io/name: thanos-query
spec:
containers:
- name: thanos-query
image: thanosio/thanos:v0.37.0
args:
- "query"
- "--grpc-address=0.0.0.0:10901"
- "--http-address=0.0.0.0:10902"
- "--log.level=info"
- "--query.replica-label=prometheus_replica"
- "--query.mode=distributed"
- "--query.auto-downsampling"
# 指向所有 Sidecar 的 Store API
- "--store=dnssrv+_grpc._tcp.prometheus.default.svc.cluster.local"
# 指向 Store Gateway
- "--store=thanos-store-gateway:10901"
# 指向 Ruler
- "--store=thanos-ruler:10901"
ports:
- containerPort: 10902
name: http
- containerPort: 10901
name: grpc
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 2
memory: 4Gi
livenessProbe:
httpGet:
path: /-/healthy
port: http
readinessProbe:
httpGet:
path: /-/ready
port: http
去重关键:
--query.replica-label=prometheus_replica告诉 Query 组件用哪个标签来识别同一数据的多个副本。如果两个 Prometheus 实例采集了相同指标,Query 会自动去重。
Store Gateway 部署
Store Gateway 充当对象存储的读取代理,让 Query 能查询到已上传的历史数据:
# thanos-store-gateway.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-store-gateway
labels:
app.kubernetes.io/name: thanos-store-gateway
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: thanos-store-gateway
template:
metadata:
labels:
app.kubernetes.io/name: thanos-store-gateway
spec:
containers:
- name: thanos-store-gateway
image: thanosio/thanos:v0.37.0
args:
- "store"
- "--data-dir=/data"
- "--grpc-address=0.0.0.0:10901"
- "--http-address=0.0.0.0:10902"
- "--objstore.config-file=/etc/thanos/objstore.yml"
- "--cache-index-header"
ports:
- containerPort: 10902
name: http
- containerPort: 10901
name: grpc
volumeMounts:
- name: data
mountPath: /data
- name: thanos-config
mountPath: /etc/thanos
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
volumes:
- name: thanos-config
configMap:
name: thanos-objstore-config
- name: data
emptyDir: {}
Compactor 部署
Compactor 负责三件事:压缩 Block、执行降采样、执行保留策略。它是单实例部署,不能多副本:
# thanos-compactor.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: thanos-compactor
labels:
app.kubernetes.io/name: thanos-compactor
spec:
serviceName: thanos-compactor
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: thanos-compactor
template:
metadata:
labels:
app.kubernetes.io/name: thanos-compactor
spec:
containers:
- name: thanos-compactor
image: thanosio/thanos:v0.37.0
args:
- "compact"
- "--data-dir=/data"
- "--objstore.config-file=/etc/thanos/objstore.yml"
- "--compact.concurrency=4"
- "--retention.resolution-raw=90d"
- "--retention.resolution-5m=180d"
- "--retention.resolution-1h=365d"
- "--wait"
ports:
- containerPort: 10902
name: http
volumeMounts:
- name: data
mountPath: /data
- name: thanos-config
mountPath: /etc/thanos
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
volumes:
- name: thanos-config
configMap:
name: thanos-objstore-config
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 100Gi
保留策略是 Compactor 最关键的配置:
| 数据精度 | 保留时长 | 适用场景 |
|---|---|---|
| Raw(原始) | 90 天 | 短期精确查询、告警评估 |
| 5min 降采样 | 180 天 | 中期趋势分析 |
| 1h 降采样 | 365 天 | 长期容量规划、年度报告 |
降采样的原理是将 2 小时原始 Block 聚合为 5 分钟或 1 小时粒度的 Block,大幅减少数据量。例如 2 小时的原始数据可能有几百 MB,降采样到 1h 粒度后只有几 KB。
Ruler 部署
Ruler 允许在 Thanos 中定义和评估告警规则,规则评估基于全局数据而非单个 Prometheus 实例:
# thanos-ruler.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-ruler
labels:
app.kubernetes.io/name: thanos-ruler
spec:
replicas: 2
selector:
matchLabels:
app.kubernetes.io/name: thanos-ruler
template:
metadata:
labels:
app.kubernetes.io/name: thanos-ruler
spec:
containers:
- name: thanos-ruler
image: thanosio/thanos:v0.37.0
args:
- "rule"
- "--grpc-address=0.0.0.0:10901"
- "--http-address=0.0.0.0:10902"
- "--data-dir=/data"
- "--rule-file=/etc/thanos/rules/*.yaml"
- "--alertmanagers.url=http://alertmanager:9093"
- "--query=thanos-query:10902"
- "--label=ruler_cluster=\"prod\""
- "--label=replica=\"$(POD_NAME)\""
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
ports:
- containerPort: 10902
name: http
- containerPort: 10901
name: grpc
volumeMounts:
- name: rules
mountPath: /etc/thanos/rules
- name: data
mountPath: /data
resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 1
memory: 2Gi
volumes:
- name: rules
configMap:
name: thanos-rules
- name: data
emptyDir: {}
告警规则文件示例 rules/global-alerts.yaml:
groups:
- name: thanos-component-health
rules:
- alert: ThanosSidecarDown
expr: up{job="thanos-sidecar"} == 0
for: 5m
labels:
severity: critical
annotations:
summary: "Thanos Sidecar 不可用"
description: "Prometheus {{ $labels.instance }} 的 Sidecar 已离线超过 5 分钟"
- alert: ThanosCompactHalted
expr: thanos_compactor_halted == 1
for: 5m
labels:
severity: critical
annotations:
summary: "Thanos Compactor 已暂停"
description: "Compactor 组件处于 halted 状态,数据压缩和降采样已停止"
- alert: ThanosQueryHighErrorRate
expr: |
sum(rate(thanos_query_concurrent_selects_gate_queries_in_flight[5m])) by (job)
/ sum(rate(thanos_query_range_requested_timespan_seconds_sum[5m])) by (job)
> 0.05
for: 10m
labels:
severity: warning
annotations:
summary: "Thanos Query 错误率过高"
description: "Query 组件 {{ $labels.job }} 的查询错误率超过 5%"
高可用设计
Query 高可用
Query 组件本身是无状态的,只需多副本部署即可。前面通过 Kubernetes Service 自动负载均衡:
apiVersion: v1
kind: Service
metadata:
name: thanos-query
spec:
selector:
app.kubernetes.io/name: thanos-query
ports:
- name: http
port: 10902
targetPort: 10902
- name: grpc
port: 10901
targetPort: 10901
配合 Grafana 使用时,将 Grafana 的 Prometheus 数据源指向 http://thanos-query:10902 即可。
Prometheus 高可用
Prometheus 高可用的核心思路是:部署两个完全相同的 Prometheus 实例(通过 prometheus_replica 标签区分),它们采集相同的目标。Thanos Query 通过 --query.replica-label 自动去重:
# Prometheus 1
- "--storage.tsdb.retention.time=6h"
- "--storage.tsdb.min-block-duration=2h"
- "--storage.tsdb.max-block-duration=2h"
# 外部标签用于区分副本
external_labels:
prometheus_replica: "prometheus-1"
cluster: "prod-cluster"
# Prometheus 2
external_labels:
prometheus_replica: "prometheus-2"
cluster: "prod-cluster"
重要:
external_labels中的prometheus_replica必须与 Query 的--query.replica-label参数一致。否则去重不会生效,查询结果会出现重复数据。
对象存储一致性
对象存储是 Thanos 的单点依赖。确保:
- MinIO 集群至少 4 节点,使用纠删码模式,容忍单节点故障
- 定期备份 bucket,防止误删
- 监控对象存储健康状态,Thanos Sidecar 上传失败会记录在
thanos_shipper_last_upload_success_timestamp_seconds指标中
性能调优
查询性能优化
Thanos 查询性能受多个因素影响,以下是一些关键调优点:
# Query 调优参数
- "--query.timeout=2m" # 单次查询超时
- "--query.max-concurrent=20" # 最大并发查询数
- "--query.max-concurrent-select=4" # 每个查询最大并发 Store API 调用
- "--query.auto-downsampling" # 自动降采样
- "--query.replica-label=prometheus_replica"
- "--query.default-evaluation-interval=30s"
--query.auto-downsampling 是一个重要特性:当查询时间跨度较长时,Query 会自动选择合适的降采样数据,而非原始数据:
| 查询时间跨度 | 自动选择精度 |
|---|---|
| < 40 小时 | Raw(原始数据) |
| 40h ~ 10 天 | 5min 降采样 |
| > 10 天 | 1h 降采样 |
这能显著减少查询数据量和响应时间。例如查询 30 天的 CPU 使用率趋势,使用 1h 降采样数据只需要原始数据量的 1/720。
Store Gateway 缓存
Store Gateway 的索引头缓存对查询性能至关重要:
# 启用索引头缓存
- "--cache-index-header"
- "--store.caching-bucket.enabled=true"
- "--store.caching-bucket.max-size=1GB"
Compactor 性能
Compactor 处理大量 Block 时可能成为瓶颈:
# 提高并发
- "--compact.concurrency=4"
# Compactor 数据目录需要足够空间
# 建议至少 100GB SSD
监控 Compactor 的关键指标:
# 压缩任务耗时
thanos_compact_iterations_total
# 对象存储操作延迟
rate(thanos_objstore_bucket_operations_duration_seconds_sum[5m])
/ rate(thanos_objstore_bucket_operations_duration_seconds_count[5m])
# 降采样产生的 Block 数量
increase(thanos_compact_downsample_total[1h])
监控 Thanos 自身
关键指标
| 指标 | 含义 | 告警阈值建议 |
|---|---|---|
thanos_shipper_last_upload_success_timestamp_seconds | 最后一次成功上传时间 | 超过 4 小时未上传 |
thanos_compactor_halted | Compactor 是否暂停 | == 1 时告警 |
thanos_query_concurrent_selects_gate_queries_in_flight | 正在执行的查询数 | 持续接近 max-concurrent |
thanos_objstore_bucket_operations_failures_total | 对象存储操作失败数 | 持续增长 |
thanos_store_grpc_client_connections_inuse | Store API 连接数 | 突然降为 0 |
thanos_ruler_evaluation_failures_total | Ruler 评估失败数 | 持续增长 |
Thanos 自监控 Dashboard
推荐使用 Thanos 官方提供的 Grafana Dashboard 模板,ID 为 14388(Thanos Overview)和 14389(Thanos Receive)。
在 Grafana 中导入后,确保数据源指向 Thanos Query 组件。核心面板包括:
- 组件健康状态:各组件的
up状态 - 上传延迟:Sidecar 上传 Block 的延迟趋势
- 查询延迟分布:P50/P95/P99 查询延迟
- 对象存储操作:读写延迟和错误率
- Compactor 运行状态:压缩和降采样进度
常见问题排查
Sidecar 上传失败
# 检查 Sidecar 日志
kubectl logs -l app.kubernetes.io/name=prometheus -c thanos-sidecar | grep -i "upload\|error"
# 检查对象存储连通性
kubectl exec -it prometheus-0 -c thanos-sidecar -- \
thanos tools bucket verify \
--objstore.config-file=/etc/thanos/objstore.yml
# 查看 Block 上传状态
kubectl exec -it prometheus-0 -c thanos-sidecar -- \
thanos tools bucket inspect \
--objstore.config-file=/etc/thanos/objstore.yml \
--output=json
常见原因:
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 上传报 403 | 凭证权限不足 | 检查 S3/MinIO 访问策略 |
| Block 一直不上传 | Prometheus Block 未完成 2h 持续期 | 检查 TSDB Block 配置 |
| 上传超时 | 网络带宽不足 | 增加 timeout 或优化网络 |
| 对象存储 bucket 满了 | 存储配额限制 | 扩容或调整保留策略 |
查询慢
# 查看 Query 的 Store API 连接状态
curl -s http://thanos-query:10902/api/v1/status/stores | jq .
# 分析慢查询
curl -s 'http://thanos-query:10902/api/v1/query?query=up' | jq .stats
优化方向:
- 启用
--query.auto-downsampling,长跨度查询使用降采样数据 - 增加 Store Gateway 副本数,分散读取压力
- 优化 PromQL 查询,避免高基数标签和全量
rate()计算 - 检查对象存储读写延迟,必要时升级存储性能
Compactor 卡住
Compactor 卡住会导致数据不被压缩和降采样,最终影响查询性能:
# 检查 Compactor 状态
curl -s http://thanos-compactor:10902/api/v1/status/config | jq .
# 查看 Block 状态
kubectl exec thanos-compactor-0 -- \
thanos tools bucket inspect \
--objstore.config-file=/etc/thanos/objstore.yml
常见原因和解决:
- 磁盘空间不足:Compactor 需要临时空间来下载和压缩 Block。增加 PVC 容量或清理
--data-dir - Block 损坏:使用
thanos tools bucket verify检查并修复损坏的 Block - 并发冲突:多副本 Compactor 同时操作。确保 Compactor 只有一个实例运行
多集群监控方案
Thanos 的一个重要场景是跨多个 Kubernetes 集群的统一监控。推荐架构:
集群 A 集群 B
┌─────────────────────┐ ┌─────────────────────┐
│ Prometheus + Sidecar│ │ Prometheus + Sidecar│
│ │ │ │ │ │
│ ┌────▼────┐ │ │ ┌────▼────┐ │
│ │ Sidecar │──────┼────────┼───►│ Sidecar │ │
│ └─────────┘ │ │ └─────────┘ │
└─────────┬───────────┘ └─────────┬───────────┘
│ │
▼ ▼
┌──────────────────────────────────────────┐
│ 对象存储 (S3/MinIO) │
└──────────────────┬───────────────────────┘
│
┌───────┴───────┐
│ Store Gateway │
└───────┬───────┘
│
┌───────┴───────┐
│ Query │ ◄── Grafana
└───────┬───────┘
│
┌───────┴───────┐
│ Ruler │ ──► Alertmanager
└───────────────┘
每个集群需要唯一的 external_labels,确保 Query 能区分数据来源:
# 集群 A 的 Prometheus
external_labels:
cluster: "cluster-a"
prometheus_replica: "prometheus-1"
# 集群 B 的 Prometheus
external_labels:
cluster: "cluster-b"
prometheus_replica: "prometheus-1"
在 Grafana 中可以通过 $cluster 变量切换查看不同集群的数据:
# 按集群查看 CPU 使用率
sum(rate(node_cpu_seconds_total{mode!="idle", cluster="$cluster"}[5m])) by (instance)
# 跨集群对比
sum(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (cluster)
成本优化
对象存储成本
Thanos 的主要成本来自对象存储。优化策略:
| 策略 | 效果 | 实施 |
|---|---|---|
| 调整保留策略 | 减少 30-50% 存储量 | 合理设置 raw/5m/1h 保留时长 |
| 采集间隔调大 | 减少数据量 | 从 15s 调整为 30s 或 60s |
| 过滤无用指标 | 减少数据量 | 使用 metric_relabel_configs |
| 生命周期策略 | 自动降级存储 | 配置 S3 Lifecycle 规则 |
计算资源成本
| 组件 | 最低资源 | 推荐资源 | 扩展方式 |
|---|---|---|---|
| Sidecar | 100m CPU / 128Mi | 200m / 512Mi | 每 Prometheus 一个 |
| Query | 500m / 1Gi | 2 CPU / 4Gi | 多副本负载均衡 |
| Store Gateway | 200m / 512Mi | 1 CPU / 2Gi | 多副本分散读取 |
| Compactor | 200m / 512Mi | 1 CPU / 2Gi | 单实例 |
| Ruler | 200m / 512Mi | 1 CPU / 2Gi | 多副本+去重 |
与其他方案对比
| 特性 | Thanos | Cortex | VictoriaMetrics |
|---|---|---|---|
| 架构模型 | Sidecar 旁路上传 | remote_write 中心化 | remote_write 中心化 |
| 对 Prometheus 改动 | 无需改动 | 需配置 remote_write | 需配置 remote_write |
| 对象存储 | 必须 | 可选 | 可选 |
| 全局查询 | 原生支持 | 原生支持 | 原生支持 |
| 降采样 | Compactor 自动 | 手动配置 | 自动 |
| 多租户 | 通过标签隔离 | 原生支持 | 原生支持 |
| 部署复杂度 | 中等 | 高 | 低 |
| 社区活跃度 | CNCF 孵化 | CNCF 孵化 | 独立项目 |
选择建议:
- Thanos:适合已有 Prometheus 部署、不想改动采集方式、需要跨集群全局查询的场景
- Cortex/Mimir:适合需要多租户、remote_write 中心化的 SaaS 场景
- VictoriaMetrics:适合追求高性能和低资源消耗、可接受厂商锁定的场景
总结
Thanos 通过 Sidecar + 对象存储 + 分布式查询的架构,优雅地解决了 Prometheus 长期存储和全局查询的问题,同时保持了对 Prometheus 的零侵入。在生产部署中,需要重点关注以下几点:
- 对象存储是基石:确保 S3/MinIO 的高可用性和数据一致性,这是整个 Thanos 体系的单点依赖
- 合理设置保留策略:Raw 数据保留 90 天满足日常告警和排障需求,5min 和 1h 降采样数据分别保留 180 天和 365 天用于趋势分析
- 高可用从 Prometheus 开始:双副本 Prometheus + replica 标签 + Query 去重,是高可用的基础
- 监控 Thanos 自身:上传失败、Compactor 暂停、查询超时等问题都需要及时发现
- 成本可控:通过保留策略、采集间隔优化和指标过滤,将对象存储成本控制在合理范围内
Thanos 的设计哲学是"每个组件只做一件事,并做好它",这种 UNIX 风格的模块化设计使得每个组件可以独立部署、扩展和运维,非常适合大规模生产环境。
参考资源
- Thanos 官方文档
- Prometheus TSDB 格式
- Thanos 存储 API 设计
- Google SRE Book — Monitoring Distributed Systems
- Thanos Bucket Inspector 工具
参考资料与致谢
本文在撰写过程中参考了以下资料,感谢原作者的贡献:
- Prometheus TSDB 格式 — Prometheus 官方,参考了Prometheus TSDB 格式相关内容
- Google SRE Book — Monitoring Distributed Systems — Google SRE 团队,参考了Google SRE Book — Monitoring Distributed Systems相关内容
- Thanos 官方文档 — Thanos 项目,参考了Thanos 官方文档相关内容
- Thanos Bucket Inspector 工具 — Thanos 项目,参考了Thanos Bucket Inspector 工具相关内容
- Thanos 存储 API 设计 — Thanos 项目,参考了Thanos 存储 API 设计相关内容
- Thanos 官方架构文档 — Thanos 项目,参考了Thanos 官方架构文档相关内容