資料與儲存 2026 年 5 月 25 日

2026-05-25 — Cloudflare ClickHouse Mutex 競爭診斷、ClickHouse 26.4 NATURAL JOIN 與 COUNT DISTINCT 提速、DuckDB Quack 協定

primary=https://blog.cloudflare.com/clickhouse-query-plan-contention/ primary=https://clickhouse.com/blog/clickhouse-release-26-04 primary=https://duckdb.org/2026/05/12/quack-remote-protocol.html

Cloudflare 診斷 ClickHouse 查詢規劃器 Mutex 競爭:從 flame graph 到上游 PR

Cloudflare Blog · 2026-05-14

Cloudflare 工程師記錄了一次 ClickHouse 效能調查:計費流水線在分區方案從 (namespace, day) 遷移後查詢開始大幅降速,即使 CPU 指標看起來正常。根本原因是查詢規劃器(query planner)對分區清單持有一把排他鎖(exclusive mutex),在 160,000+ 個分區與數百個並發查詢的規模下,超過一半的查詢時間都花在等待這把鎖上。三項優化最終合入 ClickHouse 25.11 版(上游 PR #85535)。

原本的問題

查詢規劃器的執行邏輯是:鎖定整個分區清單(排他鎖)→ 複製所有分區到記憶體 → 篩選出相關分區。隨著分區數從 30,000 增長到 160,000+,每個並發查詢都必須等待其他查詢完成複製操作後才能取得鎖,形成嚴重的串行化瓶頸。

診斷方式

初期使用 CPU flame graph 未發現異常,因為問題是等待(waiting)而非計算(computing)。關鍵突破是切換到 ClickHouse 內建 trace_log 的「Real」模式,這個模式會捕捉被阻塞的執行緒,從而讓 mutex 等待在 flame graph 中清晰可見。

三項優化

  • Shared Lock:將排他鎖改為 std::shared_lock,允許多個讀取者並發存取
  • 消除向量複製:建立分區清單的快取共享副本,規劃器只複製篩選後的結果,而非先複製全部再篩選
  • Binary Search:利用分區 ID 的有序性實作 binary search,對依 namespace 篩選的場景特別有效

影響範圍

修復後查詢時間顯著下降,且在分區數持續增長到 160k 後依然穩定。最重要的經驗是診斷工具的選擇:CPU 層面的 profiling 對於 I/O 或 lock 導致的延遲問題是盲目的,需要使用能捕捉「執行緒在等什麼」的 wall-clock/real-time profiling 工具。

原始來源:Cloudflare Blog


ClickHouse 26.4:NATURAL JOIN、JSON 子欄位索引與 COUNT DISTINCT 3–15× 提速

ClickHouse Blog · 2026-05-08

ClickHouse 26.4 釋出,共包含 39 個新功能、45 項效能優化與 238 個 bug 修復。主要亮點包括 SQL 標準相容性擴充(NATURAL JOIN、OVERLAY、EXTRACT EPOCH 等)、JSON 子欄位文字索引,以及 COUNT DISTINCT 在高核心機器上的顯著提速。

SQL 相容性擴充

  • NATURAL JOIN:根據同名欄位自動 JOIN,減少 USING 子句撰寫
  • VALUES 作為 Table Expression:現可在 FROM 子句中使用 VALUES 並指定欄位別名
  • EXTRACT EPOCH/DOW/ISOYEAR/CENTURY:支援 PostgreSQL 風格的時間單位
  • SET TIME ZONE:符合 SQL 標準的時區設定語法
  • 複合 INTERVAL 字面量:例如 INTERVAL '1 year 3 months'

效能改進

COUNT DISTINCT 在高核心機器上的提速幅度為 3–15×。原本實作在 merge 操作時對 256 個 hash table buckets 各自啟動執行緒,造成大量不必要的執行緒生成。新實作將 N 個中間 hash table 在單一 pass 中合併,執行緒池初始化複雜度從 O(N) 降為 O(1)。

LIKE 查詢透過文字索引字典掃描優化,查詢速度提升超過 3×,掃描資料量減少 80%。JSON 欄位方面,在 JSONAllValues(返回所有葉子節點值的陣列)上建立文字索引後,掃描範圍縮小約 5×,查詢時間減少約 50%。

影響範圍

NATURAL JOIN 與 EXTRACT EPOCH 的支援讓從 PostgreSQL 遷移 SQL 查詢更加平滑。對於大量使用 COUNT DISTINCT 的分析工作負載,26.4 在多核心伺服器上的提升尤其顯著,無需修改 SQL 即可受益。

原始來源:ClickHouse Blog


DuckDB Quack:基於 HTTP/TCP 的 Client-Server 協定,跨進程並行寫入終於實現

DuckDB Blog · 2026-05-12

DuckDB 團隊發布 Quack 協定,讓多個獨立進程(本地或遠端)可以並行修改同一個 DuckDB 資料庫的表格,而不受原本 in-process 架構的互斥限制。協定預設監聽 port 9494(紀念 Netscape Navigator 1994 年),連線命令為 ATTACH 'quack:localhost'

規格細節

Quack 選擇 HTTP/TCP 而非自定義二進位協定,理由是現有的負載平衡、防火牆、身份驗證基礎設施都已針對 HTTP 最佳化,無需重複發明。序列化使用自訂 MIME type application/duckdb,底層序列化原語與 Write-Ahead Log 相同,是已充分測試的成熟機制。

安全模型方面:伺服器啟動時自動生成隨機身份驗證 token,預設只綁定 localhost。對外暴露時建議透過 nginx 反向代理搭配 SSL/Let's Encrypt。

效能數據

場景QuackArrow Flight SQLPostgreSQL
60M rows 大量傳輸4.94s17.40s158.37s
8 執行緒並行小寫入~5,434 TPS~1,358 TPS~4,320 TPS

影響範圍

Quack 是 DuckDB 從「嵌入式分析引擎」走向「可部署資料服務」的關鍵一步。目前在超過 8 個並行執行緒時吞吐量會達到瓶頸,這是 DuckDB 並行插入架構本身的限制,團隊已列入未來優化方向。對於需要多個服務共享一個 DuckDB 資料庫的架構,Quack 是目前唯一的官方方案。

原始來源:DuckDB Blog


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