結論先講

如果你已經有 PostgreSQL,用 TimescaleDB。如果你是做 Kubernetes 監控,用 Prometheus + VictoriaMetrics 當長期儲存。 InfluxDB 不是不好,但它的查詢語言換了三次(InfluxQL → Flux → SQL),社群信任度已經打折。

關鍵判斷:你的資料是「指標型」(CPU、記憶體、QPS)還是「事件型」(log、交易紀錄)?前者用時序資料庫,後者用 Elasticsearch 或 ClickHouse 更合適。


什麼是時序資料?

時序資料(time-series data)有三個特徵:

  1. 每筆資料都有時間戳——這是最重要的維度
  2. 只追加不修改——你不會回去改昨天的 CPU 使用率
  3. 查詢永遠帶時間範圍——「最近 5 分鐘」「過去 7 天」「上個月同期」

常見的時序資料:

領域資料範例寫入頻率
伺服器監控CPU、記憶體、磁碟、網路流量每 10-30 秒
應用指標API 回應時間、錯誤率、QPS每秒
IoT 感測器溫度、濕度、加速度每秒到每毫秒
金融報價股價、匯率、加密貨幣每毫秒
能源發電量、用電量每分鐘

為什麼一般資料庫扛不住?

我們用一個實際場景來說明:100 台伺服器,每台收集 50 個指標,每 10 秒寫入一次。

100 台 × 50 指標 × 6 次/分鐘 × 60 分鐘 × 24 小時 = 4,320 萬筆/天

一個月就是 13 億筆。用 MySQL 或 PostgreSQL 存會遇到什麼問題?

問題說明
寫入效能每秒 5000 筆 INSERT,一般 DB 可以撐,但加上索引就開始吃力
查詢效能WHERE timestamp > now() - interval '1 hour' 在 13 億筆的表上,即使有索引也慢
儲存成本每筆資料帶索引大約 100-200 bytes,13 億筆 = 130-260 GB/月
資料保留刪除 30 天前的資料需要 DELETE,大量刪除會鎖表
降精度「最近 1 小時看秒級、最近 7 天看分鐘級、最近 30 天看小時級」——一般 DB 沒有內建這個功能

時序資料庫用專門的儲存引擎解決這些問題:列式壓縮、時間分片、自動降精度、TTL 過期策略。


四大時序方案比較

特性InfluxDBTimescaleDBPrometheusVictoriaMetrics
本質專門時序 DBPG extension監控系統監控儲存
查詢語言SQL (v3) / InfluxQLSQLPromQLMetricsQL (PromQL 超集)
儲存引擎自研 (IOx/Arrow)PostgreSQL + 壓縮自研 TSDB自研 (merge tree)
壓縮率高(原生壓縮)極高(比 Prometheus 低 7 倍儲存)
水平擴展Cloud 版才有有(multi-node)單節點有(cluster 版)
長期儲存原生原生需要外部方案原生
生態Telegraf + Grafana任何 PG 工具 + Grafanak8s 原生Prometheus 兼容
授權MIT (v3)Apache 2.0Apache 2.0Apache 2.0
適合場景IoT、通用時序已有 PG、想用 SQLK8s 監控大規模 Prometheus

InfluxDB:元老級時序資料庫

InfluxDB 是最早把「時序資料庫」這個概念帶進主流的產品。但它的歷史也是最混亂的:

  • v1:InfluxQL(類 SQL),穩定但功能有限
  • v2:改用 Flux(函數式語言),社群大量反彈
  • v3:又回到 SQL(基於 Apache Arrow),架構大改
-- InfluxDB v3 SQL 查詢
SELECT time, host, mean(cpu_usage)
FROM cpu
WHERE time > now() - INTERVAL '1 hour'
GROUP BY time(5m), host

優點:成熟、文件多、Telegraf 收集器生態豐富。 缺點:版本升級路徑混亂,v1 到 v3 基本上是三個不同的產品。開源版 v3 功能有限。


TimescaleDB:會 SQL 就會用

TimescaleDB 是我最推薦的入門選擇。它就是 PostgreSQL 的 extension,所有 SQL 語法、所有 PG 工具、所有 ORM 都能用。

-- 建立 hypertable(時序表)
CREATE TABLE metrics (
    time        TIMESTAMPTZ NOT NULL,
    host        TEXT,
    cpu_usage   DOUBLE PRECISION,
    mem_usage   DOUBLE PRECISION,
    disk_usage  DOUBLE PRECISION
);
 
SELECT create_hypertable('metrics', 'time');
 
-- 自動壓縮(7 天後壓縮)
ALTER TABLE metrics SET (
    timescaledb.compress,
    timescaledb.compress_segmentby = 'host'
);
 
SELECT add_compression_policy('metrics', INTERVAL '7 days');
 
-- 資料保留(自動刪除 90 天前的資料)
SELECT add_retention_policy('metrics', INTERVAL '90 days');
 
-- 查詢:最近一小時每 5 分鐘的平均 CPU
SELECT time_bucket('5 minutes', time) AS bucket,
       host,
       avg(cpu_usage) AS avg_cpu
FROM metrics
WHERE time > now() - INTERVAL '1 hour'
GROUP BY bucket, host
ORDER BY bucket DESC;

殺手功能

  • time_bucket():自動依時間分桶聚合
  • 壓縮:舊資料自動壓縮,儲存空間省 90%+
  • Continuous Aggregates:預計算的 materialized view,查詢秒回
  • 跟業務資料 JOIN:因為就是 PG,你可以直接 JOIN users ON ...

Prometheus:Kubernetes 監控的標準配備

Prometheus 不太算「資料庫」,更像是一個完整的監控系統。它的特色是 pull-based:Prometheus 主動去抓各服務的 /metrics endpoint。

# prometheus.yml
scrape_configs:
  - job_name: 'node-exporter'
    scrape_interval: 15s
    static_configs:
      - targets: ['localhost:9100']
 
  - job_name: 'api-server'
    scrape_interval: 10s
    kubernetes_sd_configs:
      - role: pod
# PromQL 查詢範例
 
# 最近 5 分鐘的平均 CPU 使用率
avg(rate(node_cpu_seconds_total{mode!="idle"}[5m])) by (instance)
 
# API 回應時間 P99
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
 
# 錯誤率
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))

Prometheus 的問題

  1. 單節點架構——不能水平擴展
  2. 預設保留 15 天——長期儲存需要外接方案
  3. PromQL 學習曲線——跟 SQL 完全不同的思維

這就是 VictoriaMetrics 登場的原因。


VictoriaMetrics:更好的 Prometheus

VictoriaMetrics 的定位很明確:Prometheus 的長期儲存替代品。它完全兼容 Prometheus 的 remote write 協議和 PromQL(還有擴展版的 MetricsQL)。

對比PrometheusVictoriaMetrics
儲存空間1x0.14x(省 86%)
寫入效能1x2-5x
查詢效能1x2-10x
水平擴展不支援支援(cluster 版)
長期保留需外接原生支援
資源消耗

典型架構:Prometheus 短期保留(2 天),remote write 到 VictoriaMetrics 做長期儲存。Grafana 查詢指向 VictoriaMetrics。

# Prometheus remote write 到 VictoriaMetrics
remote_write:
  - url: http://victoriametrics:8428/api/v1/write

決策流程圖

你的資料是時序的嗎?
├── 不是 → 用一般資料庫
└── 是
    ├── 已有 PostgreSQL?
    │   ├── 是 → TimescaleDB(加 extension 就好)
    │   └── 否 ↓
    ├── 是 Kubernetes 監控?
    │   ├── 是 → Prometheus + VictoriaMetrics
    │   └── 否 ↓
    ├── IoT / 工業場景?
    │   └── InfluxDB + Telegraf
    └── 不確定 → TimescaleDB(最泛用)

什麼時候用 PostgreSQL + 時間索引就好?

不是所有時間相關的資料都需要時序資料庫。如果你的情況符合以下條件,一般的 PostgreSQL 加個複合索引就夠了:

-- 普通 PostgreSQL 時間索引
CREATE INDEX idx_events_time ON events (created_at DESC);
 
-- 搭配 BRIN 索引(適合時序自然排列的資料)
CREATE INDEX idx_events_brin ON events USING BRIN (created_at);

適合用一般 PG 的情況

  • 每天寫入少於 100 萬筆
  • 不需要自動降精度
  • 不需要自動壓縮和資料保留策略
  • 資料需要跟其他表頻繁 JOIN

需要時序資料庫的訊號

  • 寫入量超過每秒 1000 筆
  • 需要自動 downsampling
  • 資料保留需要 TTL 管理
  • 儲存成本開始讓你心痛

常見問題

InfluxDB v3 值得用嗎?

如果你是全新專案、沒有歷史包袱,可以考慮。InfluxDB v3 改用 Apache Arrow 引擎、支援標準 SQL,方向是對的。但它剛推出不久,生態和穩定度還需要時間驗證。已有 v1 的專案建議直接遷到 TimescaleDB,升級路徑反而更明確。

TimescaleDB 跟普通 PostgreSQL 差多少?

主要差在大量時序資料的場景。10 萬筆以下你幾乎感覺不到差異。超過 100 萬筆,TimescaleDB 的 hypertable 分片和壓縮就會明顯比普通 PG 表快。而且 time_bucket() 和 continuous aggregates 大幅簡化了時序查詢的 SQL。

Prometheus 資料最多能存多久?

Prometheus 本身建議保留 15 天到 30 天。超過這個期間,用 remote write 寫到長期儲存(VictoriaMetrics、Thanos、Cortex)。不要嘗試讓 Prometheus 存半年的資料——它不是設計來做這件事的。

可以用 Elasticsearch 存時序資料嗎?

可以,Elasticsearch 的 data stream 和 ILM(Index Lifecycle Management)支援時序場景。但 Elasticsearch 的資源消耗遠高於專門的時序資料庫,而且指標查詢的效能不如 Prometheus / VictoriaMetrics。用 Elasticsearch 存 log 很合適,存 metrics 則浪費錢。

Grafana 支援哪些時序資料庫?

全部都支援。Grafana 有 Prometheus、InfluxDB、TimescaleDB(走 PostgreSQL datasource)、Elasticsearch 的原生 data source。VictoriaMetrics 用 Prometheus data source 就能查。這也是為什麼大家都用 Grafana——它不綁定任何特定資料庫。


本系列文章

  1. 資料庫全景:SQL vs NoSQL vs NewSQL
  2. MySQL:為什麼越來越多人覺得它不夠好?
  3. PostgreSQL:為什麼越來越多人轉
  4. NoSQL 什麼時候該用
  5. 資料庫設計:正規化與索引策略
  6. 向量資料庫:RAG 時代的 Embedding 儲存方案
  7. 時序資料庫:監控資料用一般 DB 存,你會後悔(本篇)
  8. MongoDB vs PostgreSQL:什麼時候該用 NoSQL?
  9. 資料庫設計模式:正規化、反正規化、分表的取捨
  10. 擴展策略:讀寫分離與分片
  11. Docker 環境的資料庫管理
  12. 資料庫安全:從連線加密到欄位加密