資料與儲存 2026 年 9 月 16 日

2026-09-16 — ClickHouse TimeSeries 引擎:PromQL 原生查詢時序資料

primary=https://clickhouse.com/blog/introducing-promql primary=https://clickhouse.com/docs/engines/table-engines/special/time_series primary=https://clickhouse.com/docs/reference/functions/table-functions/prometheusQueryRange

ClickHouse TimeSeries 引擎:PromQL 原生查詢時序資料

ClickHouse · 2026-09-15

ClickHouse 讓 PromQL 查詢直接在自家的 TimeSeries 資料表引擎上執行,取代過去得先用 remote-write 把指標塞進一般資料表、再手刻 SQL 重現 rate()histogram_quantile() 這類邏輯的作法。這項功能目前以 private preview 形式開放申請,PromQL 語法涵蓋率達 85%,且尚未支援 ClickHouse Cloud。

原本的問題

Prometheus 本身只設計給短期本地儲存,需要長期留存指標的團隊,過去只能挑 Thanos、Cortex、Mimir 之類的擴充方案,或是把資料 remote-write 進 ClickHouse 這種通用資料庫、自己用 SQL 重寫儀表板。後者最麻煩的地方在於語意:ClickHouse 官方部落格點名 PromQL 之所以長這樣,是因為 Prometheus 架構本身是 pull-based、在 scrape 當下加時間戳、並用 type-aware 編碼區分 counter、gauge、histogram 等指標型別,而標準 SQL 沒辦法直接表達這些概念,必須額外寫邏輯手動補。

結果是每次把儀表板搬到 ClickHouse,工程師都得重新刻一次 rate()irate()histogram_quantile() 的語意,只要哪個細節沒對齊,查詢結果就會悄悄跟 Prometheus 原生答案不一樣,卻不會有任何錯誤訊息提醒。這種落差不只是麻煩:只要有人拿這份 SQL 查詢結果去觸發告警或算計費,語意跑掉就可能變成誤判。

規格細節

TimeSeries 引擎把一張邏輯表拆成四張實體表。對外只看到 metric_nametags Map(String, String)samples Array(Tuple(DateTime64(3), Float64)) 幾個欄位;底層則是 samples 表(MergeTree,依 (id, timestamp) 排序,timestamp 用 DoubleDelta+ZSTD(1) 編碼、value 用 ZSTD(3))、可選的 recent samples 表(預設 TTL 345600 秒,也就是 4 天,每 5 小時分區一次)、tags 表(AggregatingMergeTree)與 metrics 表(ReplacingMergeTree)。建表可以簡單到一行:

CREATE DATABASE prometheus;
CREATE TABLE prometheus.metrics ENGINE = TimeSeries;

目前 schema 版本是 version = 3,而且短短三版就動過兩次結構:v1 加入 version 設定、v2 加入 id_typeid_generator 讓外部表能獨立指定識別欄位型別、v3 把原本叫 time_series 的欄位改名成 samples。查詢端則新增 prometheusQueryRange()prometheusQuery() 兩個 table function,直接吃 PromQL 字串:

SELECT * FROM prometheusQueryRange(mytable,
  'rate(http_requests{job="prometheus"}[10m])[1h:10m]',
  now() - INTERVAL 10 MINUTES, now(), INTERVAL 1 MINUTE)

寫入走 Prometheus remote-write v1 協定,也支援 OpenTelemetry Collector 的 Prometheus remote-write exporter;查詢端一共開放四種介面,語意評估全部搬到伺服器端執行:

  • SQL:prometheusQueryRange()prometheusQuery() table function
  • Grafana:原生 Prometheus 資料源相容
  • CLI:clickhouse-client --dialect promql
  • ClickStack:直接畫圖與建儀表板
舊做法新做法
寫入指標remote-write 進普通資料表,schema 自己設計remote-write 進 TimeSeries 引擎,四張底層表自動產生
查詢方式rate()histogram_quantile() 手刻成 SQL直接呼叫 prometheusQueryRange() 送原生 PromQL
語意正確性依賴工程師手動比對,容易跟 Prometheus 結果有落差伺服器端依 Prometheus 語意評估,官方稱涵蓋率 85%

識別欄位的設計也值得注意:預設 idTuple(UInt64, LowCardinality(UUID)),把 metric_name 與 tags 雜湊後的結果用 LowCardinality 字典編碼存起來,換取磁碟 I/O 變少;想自訂的話可以透過 id_generator 設定(例如換成 sipHash64(tags)),或直接用 INNER COLUMNS 指定 UUID、UInt64、UInt128、FixedString(16) 等型別組合。

影響範圍

已經用 remote-write 把指標塞進 ClickHouse、自己刻 SQL 模擬 PromQL 的維運團隊,可以檢查現有查詢能不能直接換成 prometheusQueryRange()prometheusQuery(),省掉那層手工轉譯與跟著維護的風險。用 Grafana 接 ClickHouse 當 Prometheus 資料源的人,也值得測一次原生 PromQL dialect 相容度,看看儀表板能不能直接搬過去。

這次私有預覽只涵蓋儲存與查詢,既有的 Prometheus scrape 基礎設施不用換掉;但 Native Histograms、不重複資料的 downsampling、Recording Rules 與 Alerting Rules 評估、OpenMetrics 與 remote-write v2、直接 OTLP 寫入等功能,官方列在之後才做的路線圖裡,現階段還不能拿來取代 Prometheus 的告警管線。

正在評估拿 ClickHouse 取代 Thanos、Cortex、Mimir 做長期儲存的團隊要注意,這仍是 private preview,尚未支援 ClickHouse Cloud,需要自建叢集開啟 enable_time_series_table = 1 才能建表,而且以下幾個常用的 range function 還沒做:

  • predict_linear
  • quantile_over_time
  • stddev_over_time
  • stdvar_over_time
  • present_over_time

儀表板若用到上述函式,得先保留原本的查詢管線。另外 schema 短時間內已經歷 v0 到 v3 的調整,private preview 期間結構還可能再變,正式導入前建議先在測試叢集跑過一輪,別直接對生產資料建表。

原始來源:ClickHouse BlogTimeSeries 引擎文件prometheusQueryRange 文件


End of article
0
Would love your thoughts, please comment.x
()
x