跳至主要内容

Thanos 架構介紹

Thanos 是 Prometheus 的水平擴展層,不替換 Prometheus,而是在它上面加元件。 核心思想:把 Prometheus 的短期資料(熱資料)和 S3 的長期資料(冷資料)統一成一個查詢界面。


為什麼需要 Thanos

Prometheus 單節點的限制:

問題說明
單點故障一個 Prometheus 掛掉就沒有資料
垂直擴展上限RAM 放不下超過約 100 萬個 active series
資料保留有限EBS 成本隨保留期線性增長;90 天就很貴
無跨實例查詢多個 Region 的 Prometheus 相互獨立,查詢無法跨越

Thanos 解決:高可用(多個 Prometheus 互備)+ 長期保留(S3)+ 統一查詢(Query 層聚合)。


核心元件

Thanos Sidecar

部署: 跟 Prometheus 同 Pod(sidecar container 模式)

Prometheus Pod:
┌────────────────────────────────────────────┐
│ container: prometheus ─┐ │
│ │ mount /data │
│ container: thanos-sidecar ─┘ │
│ │
│ shared volume (PVC): /data │
└────────────────────────────────────────────┘

跟 Prometheus 的關係

  • 共享 PVC:兩個 container mount 同一個 /data volume
  • 共享 network namespace:sidecar 可以打 localhost:9090

三大職責

1. 暴露 gRPC StoreAPI :10901 給 thanos-query 取資料

★ 取資料時 sidecar 直接讀 /data 上的 TSDB 檔案,不會反向去打 Prometheus 的 HTTP API。

2. 每 2h 把 Prometheus 完成的 TSDB block 上傳 S3

★ 走 HTTPS REST + IRSA,跟 gRPC 無關。 ★ 看 /data 目錄有新 block 就 upload,不問 Prometheus

3. 充當「最近 2h 資料」的查詢端點

★ 不是 proxy 去問 Prometheus。 ★ 是自己讀 /data還沒被 upload / 還在 WAL 的資料。

跟 Prometheus HTTP API 的關係

Sidecar 確實會打 localhost:9090,但只用在 metadata / 控制訊號

時機用途
啟動時call 一次拿 external_labels + 確認 flags
每 30 秒heartbeat 確認 Prometheus 還活著
Prometheus shutdown 時call snapshot 強制 flush

★ 這些都不是 metric 資料。Metric 資料 100% 透過共享 PVC 拿。

用比喻記住

想像對應
Prometheus = 房東,每天寫日記放抽屜/data 上的 TSDB block
Sidecar = 室友,會自己開抽屜看日記/data 上的 block
/data PVC = 兩人共用的抽屜shared volume
localhost:9090 = 房東房間門口的對講機拿 metadata 用
gRPC :10901 = 室友家對外的電話給 querier 打進來
S3 SDK = 室友自己寄日記到雲端的快遞upload block

重點:室友從來不問房東「日記寫了什麼」,他自己開抽屜看。

⚠️ 避免誤解的用詞

讀 Prometheus」這個詞模糊,會誤導:

寫法意思
❌ 讀 Prometheus模糊 — 會被當成 API 呼叫
✅ 讀 Prometheus 寫到 /data 的 TSDB 檔案精確 — 透過 PVC,不是 API

未來看到「讀 Prometheus」就改成「讀 Prometheus 寫到 /data 的 TSDB 檔案」,誤解就不會發生。

Thanos Query

職責:

  • 提供統一的 PromQL API(Grafana 連這裡,不連 Prometheus)
  • 向多個「Store API endpoint」發送查詢,合併結果
  • 自動去重:同一個時間序列若來自多個 Prometheus(HA 對),保留一份
Thanos Query:
收到 Grafana 的 PromQL 請求

├──▶ Sidecar (Region A) — 最近 2 小時
├──▶ Sidecar (Region B) — 最近 2 小時
├──▶ Sidecar (Region C) — 最近 2 小時
└──▶ Store Gateway — 超過 2 小時的歷史資料(從 S3 讀)

合併結果後回傳給 Grafana

Thanos Store Gateway

職責:

  • 把 S3 裡的 TSDB block 變成 gRPC Store API
  • Thanos Query 透過它查詢歷史資料
  • 有 bucket cache — 常查的時間範圍在記憶體裡緩存
S3 bucket:
blocks/
├── 01GXXXXXX/ ← 2 小時的 block,已壓縮
├── 01GYYYYYY/
└── ...

Store Gateway 把這些 block 提供成可查詢的 API
(不需要把整個 block 下載下來才能查詢,支援稀疏讀取)

Thanos Compactor

職責:

  • 定期把 S3 裡的小 block 合併成大 block(降低 S3 API 費用和查詢時的讀取量)
  • 執行 downsampling:raw → 5min 解析度(40 天後);5min → 1h 解析度(5min 資料累積 10 天後)
  • 全域唯一,不建議多個同時跑 — 針對相同 block range 的兩個 Compactor 會造成資料損毀(新版支援 tenant 分片,但需明確設定)
S3 原始(很多小 block):
[2h][2h][2h][2h][2h][2h][2h][2h][2h][2h][2h][2h]

Compact 後(大 block,節省 S3 API 費用):
[2h][2h] → [24h]
[24h][24h][24h][24h][24h][24h][24h] → [1w]

Downsampling(超過 40 天,5min 解析度):
原始 15s scrape → 5min 平均

Thanos Query Frontend(可選)

職責:

  • 在 Thanos Query 前面加快取層(Memcached 或 Redis)
  • 把長時間範圍的查詢拆成多個短範圍查詢並行
  • 降低 Thanos Query 的 RAM 壓力

完整資料流

寫入路徑(Sidecar 模式)

Prometheus(每個 Region):
1. 照常 scrape targets 每 15s
2. 資料存入本地 TSDB(2 小時一個 block,WAL 緩衝)
3. Block 完成後,Sidecar 自動上傳到 S3:
PUT s3://thanos-blocks/01GXXXXXX/chunks/000001
PUT s3://thanos-blocks/01GXXXXXX/meta.json
PUT s3://thanos-blocks/01GXXXXXX/index

查詢路徑

Grafana ──PromQL──▶ Thanos Query Frontend(快取 + 拆分)

Thanos Query(fan-out 聚合)
│ │
Sidecar gRPC Store Gateway gRPC
(最近 2 小時, (歷史資料,
直讀 Prometheus TSDB) 從 S3 讀 block)

Receive 模式(push-based 替代)

每個 Region Prometheus:
remote_write ──▶ Thanos Receive(hashring 分片)

local TSDB + 上傳 S3

Thanos Query + Store Gateway(同 Sidecar 模式)

Receive 模式讓 Prometheus 不需要加 Sidecar container,但 central 端的 Receive 元件更複雜(需要 hashring 設定來做 sharding)。


高可用設計

Prometheus HA 對

Region A:
Prometheus-0 ──Sidecar──▶ S3(上傳 block)
Prometheus-1 ──Sidecar──▶ S3(上傳相同 block)

兩個 Prometheus 抓一樣的 targets → S3 裡有重複的 block
Thanos Query deduplication(必要設定):
- 設定 --query.replica-label=prometheus_replica
- Query 自動識別 "prometheus_replica" 不同但其他 label 相同的 series,保留一份
- ⚠️ 若沒有設定此 flag,兩個 Prometheus 的資料都會出現在查詢結果,數值翻倍

Store Gateway HA

Store Gateway × 2:
兩個都指向同一個 S3 bucket
Thanos Query 向兩個都發查詢,取最快回來的那份
任一個掛掉,查詢繼續正常

元件資源需求(參考規模:~5M active series)

元件CPURAM備註
Thanos Sidecar0.1-0.5 vCPU128-512Mi跑在 Prometheus pod 旁,輕量
Thanos Query1-4 vCPU2-8Gi隨同時查詢數增加
Thanos Query Frontend0.5-1 vCPU512Mi-2Gi快取 reduce Query 負載
Thanos Store Gateway1-2 vCPU2-4Gi有 bucket cache 時 RAM 可能更高
Thanos Compactor1-2 vCPU2-4Gi壓縮時 RAM 使用量大

Thanos 適合的場景

場景說明
資料保留超過 3 年S3 的成本遠低於 EBS 長期保留
需要 downsampling老資料降採樣節省儲存和查詢時間
多個 Prometheus 跑相同 targets(HA)Query 層自動 dedup,不需手動處理
已有 S3 大量使用經驗依賴不是負擔
Prometheus 生態已深度整合不想碰 TSDB 底層,只加一層擴展