為什麼我們再次重構資料倉儲:PostHog 從 DuckDB 轉向 Trino 與 HogLake 的架構演進

Cover

SOURCE | 資訊源評估

NAPKIN | 餐巾紙

公式白話解析:要把雲端資料倉儲做大做穩,不能把單機引擎硬搬上雲。必須用分散式引擎(Trino)搭配靈活的 HTTP 路由放大吞吐量;

餐巾紙草圖

┌──────────────────────────────────────────────────────────────
│ [過去:DuckDB + DuckLake + pgwire (單機思維雲端化)]
│   ├── 算力層:事前盲猜客戶 Worker 規格 -> OOM 溢寫磁碟或成本失控
│   ├── 儲存層:每次 Commit 重讀全 Catalog 統計 -> 單表寫入 > 3 分鐘
│   └── 網路層:Port 5432 有狀態長連線 -> NLB 負載均衡弱、方言相容黑洞
│
│ [現在:Trino + HogLake + HTTP (原生分散式雲端架構)]
│   ... (架構拓撲持續流轉)
│   └── 網路層:HTTP Header 靈活路由 (ALB/K8s) -> 無狀態高併發擴展
└──────────────────────────────────────────────────────────────

ROUND 1: SKELETON | 骨架掃描

“這篇文章在解決什麼根本問題”

章節骨架

  1. 單機王者上雲的水土不服(DuckDB is brilliant on one machine):探討單機引擎在本地端靠磁碟溢。
  2. 相容性與規模化的零和博弈(DuckLake is built for compatibility, not scale):剖。
  3. **網路協定與最終架構轉向(Speaking Postgres is harder than it sounds & Rebuild。

ROUND 2: DISSECTION | 血肉解剖

“憑什麼這麼說:論證與硬核證據”

論證鏈

┌──────────────────────────────────────────────────────────────
│ [前提1: 客戶查詢複雜度超預期,單機 DuckDB 需在查詢到達前預先決定 Worker 規格]
│   --> [前提2: 放大機器太貴、溢寫雲端磁碟太慢,且無法向用戶預告查詢所需 CPU/RAM]
│   --> [前提3: DuckLake 受限於跨 DB 通用 Schema,2PB/1530萬快照下每次寫入重讀全庫統計]
│   --> [前提4: 99% 統計資料屬已刪除表,清理後寫入快 30-50 倍但迅速復發,且 pgwire 難以擴展]
│   --> [結論: 必須放棄單機引擎與通用輕量 Catalog,轉向分散式 Trino + 專屬優化的 HogLake]
└──────────────────────────────────────────────────────────────

關鍵證據與量化數據

  1. Catalog 寫入延遲與垃圾膨脹數據:在 PostHog 規模下,單表寫入耗時超過 3 分鐘,因每次 Commit。
  2. Dogfooding 極限規模指標:PostHog 將自身全量資料放入 DuckLake 實測,下線遷移時總資料量達 **2。
  3. 時間與工程沉沒成本:距離上次從 ClickHouse 遷移至 DuckDB 僅過 5 個月,團隊便花費最近 3 個月 全面翻新架構;

隱形假設與邊界條件

ROUND 3: SOUL | 靈魂提取

“如何落地與架構反思”

留白提問 (Guided Reflection)

跨域映射

DEEP READ | 精讀指引 (Must-Read Segments)

[!IMPORTANT] 學習的本質需要「認知阻力」。請回到原文精讀以下核心技術段落:

  1. DuckDB is brilliant on one machine(單機引擎在雲端的資源預估死結)
    • *「To run a single-node engine safely in the cloud, we have to size。
    • 推薦理由:點破「萬物皆可 DuckDB」浪潮下的雲端落地盲區——在按量計費、講求 SLA 的雲端代管服務中,無法在查詢解析前。
  2. **DuckLake is built for compatibility, not scale(Catalog 元資料的 30~5。
    • *「At our scale, a single-table write could take more than three mi。
    • 推薦理由:展示當系統為維持「跨 SQL 資料庫通用相容」而放棄特定引擎底層優化時,元資料(Metadata)本身就會退化成比。

STRUCTURE MAP | 全書結構圖

┌──────────────────────────────────────────────────────────────
│ 為什麼 PostHog 再次重構資料倉儲 (從 DuckDB 轉向 Trino + HogLake)
│ ├── 1. 前情提要與轉折
│ │      ├── 5 個月前:棄 ClickHouse (無 CBO、長查詢崩潰) 轉投 DuckDB
│ │      └── 3 個月前:客戶負載超預期,決定徹底移除 DuckDB 重新架構
│ ├── 2. 算力層瓶頸:DuckDB 單機模型的雲端困境
│ │      ├── 優勢反轉:本地 Spill-to-disk 可靠,雲端掛載大磁碟卻又慢又貴
│   ... (架構拓撲持續流轉)
│        └── 開放表格式:自研 HogLake,通過 PB 級內部 Dogfooding 驗證
└──────────────────────────────────────────────────────────────

為什麼我們再次重構資料倉儲:PostHog 從 DuckDB 轉向 Trino 與 HogLake 的架構演進 (Architectural Deep Dive)

前言

五個月前,PostHog 為克服共用 ClickHouse 叢集執行數小時長查詢(Modeling Queries)時的資源排擠,以及缺乏基。

章節詳細總結

1. 算力調度悖論:單機引擎雲端化的資源預估與 I/O 瓶頸

DuckDB 核心哲學是在單節點榨乾硬體效能,記憶體不足(OOM)時靠磁碟溢寫(Spill-to-disk)確保查詢不崩潰。

┌──────────────────────────────────────────────────────────────
│ [單機引擎雲端調度死結]
│ 客戶提交複雜 SQL ──> 調度器被迫「事前盲猜」所需 CPU/RAM
│                       ├── 猜太小 ──> 觸發雲端磁碟 Spill ──> 延遲暴增、查詢超時
│                       └── 猜太大 ──> 啟動昂貴巨型 VM ──> 算力閒置、毛利遭侵蝕
│
│ [Trino 分散式彈性調度]
│ 客戶提交複雜 SQL ──> Coordinator 解析並切分為細粒度 Splits
│                       └── 動態分發至共享 Worker 叢集 ──> 水平吸收突發負載
└──────────────────────────────────────────────────────────────

架構權衡 (Trade-offs)

2. 儲存與元資料危機:DuckLake 在 1 兆列規模下的 Catalog 崩潰

PostHog 將全量生產資料投入 DuckLake 進行 Dogfooding。當規模達 2 PB、1 兆列、1,530 萬個快照。

-- 模擬 DuckLake 在高頻快照下的元資料退化情境
-- 每次 Commit 觸發全範圍統計掃描,其中 >99% 為已刪除表的殘留紀錄
SELECT table_id, column_stats, row_count 
FROM ducklake_catalog_statistics 
WHERE catalog_version <= CURRENT_SNAPSHOT(); 
-- 缺乏高效 Partition Pruning 與非同步 GC,導致單次寫入鎖定並耗時 > 180 秒

架構權衡 (Trade-offs)

3. 網路傳輸與協定層重構:為什麼放棄 pgwire 轉向 HTTP 與 Trino

起初透過 Port 5432 提供 pgwire 看似能無痛銜接 BI 與 dbt 工具,實則在雲端規模化運維中帶來三大災難:

┌──────────────────────────────────────────────────────────────
│ [舊架構:pgwire (Port 5432 TCP 長連線)]
│ 多樣化 PG Clients ──> AWS NLB (L4 僵化轉發) ──> 狀態化連線維持 (高成本)
│   └── 痛點:TTL/Idle 管理困難、缺乏 Header 路由、無止盡的 Client 方言修補
│
│ [新架構:HTTP/REST 協定 + Trino + HogLake]
│ 標準化客戶端 ──> AWS ALB / K8s Ingress (依 HTTP Header 精準路由)
│   └── 優勢:無狀態短連線高併發、雲端原生負載均衡、擺脫 PG 相容性泥淖
└──────────────────────────────────────────────────────────────

架構權衡 (Trade-offs)

總結與結論

Source URL: https://x.com/posthog/status/2117351603514793997