從 OLTP 到 OLAP#

到此為止本章節談的都是 OLTP(線上交易):訂單、商品、購物車、賬戶。但電商還有大量分析需求:

  • 用戶行為日誌(每個點擊、每個瀏覽)
  • 推薦系統訓練資料
  • BI 報表(銷量、轉化、留存)
  • 風控規則計算
  • 個性化定價

這些是 OLAP(線上分析),特性:

維度OLTPOLAP
寫入單筆即時批次或流
讀取單筆 / 小範圍跨百萬行聚合
並發
延遲< 100ms秒到分鐘可接受
資料模型行式列式
規模TBPB
一致性弱(分析可容忍)

兩個世界用不同儲存、不同思考。

前端埋點之類的「海量原始資料」#

埋點:用戶在 app 上做的每個動作都記錄一條。

每用戶每天 ~100 條
1000 萬日活 → 10 億條/天
平均 1 KB/條 → 1 TB/天

這量根本不該存 MySQL ── 用對的工具:

client → API → Kafka → ?
                       ├─ 即時:Flink 流式處理
                       ├─ 短期:ClickHouse(分鐘級可查)
                       └─ 長期:HDFS / S3(PB 級存檔)

Kafka:管道的脊椎#

Kafka 在資料架構中扮演緩衝 + 解耦 + 重播的角色:

+-----------+     +-------+     +-----------+
| Producers |───→ | Kafka |───→ | Consumers |
+-----------+     +-------+     +-----------+
                  topics +
                  partitions
                  (分散在多 broker)

特性:

  • 寫入吞吐極高(100 萬 QPS / 叢集)
  • 訊息保留可設定(小時、天、TB)
  • 多 consumer group 各自獨立 offset
  • 順序:partition 內保證順序

Topic、Partition、Consumer Group#

topic: user_events
  ├─ partition 0   ──→ broker 1
  ├─ partition 1   ──→ broker 2
  ├─ partition 2   ──→ broker 3
  └─ partition 3   ──→ broker 4

partition 是並行單位 ── 一個 consumer group 最多能有 partition 數的 consumer 並行。

producer 寫入 partition 策略:

  • 沒指定 key → round-robin
  • 指定 key → hash(key) % num_partitions,同 key 同 partition(保順序)

Kafka 在電商的典型用法#

場景topicproducerconsumer
用戶行為user_eventsAPI gateway流處理、ML 訓練、ClickHouse
訂單事件order_lifecycleorder service庫存、支付、配送、分析
商品變更product_updatesproduct CDCsearch index、cache 失效
計費 / 報表billing_eventsvarious結算系統
系統日誌app_logslog shipperELK、長期歸檔

HDFS:更大的儲存#

Kafka 適合「短期持有 + 流式消費」,但保留 PB 級 / 多年 → 太貴。轉到 HDFS 或物件儲存(S3):

Kafka ──Flink/Spark──→ Parquet files on HDFS / S3

HDFS 特性:

  • 為大檔(128 MB block)批次處理優化
  • 高吞吐順序讀
  • 與 MapReduce / Spark 緊密整合

近年趨勢:HDFS 被物件儲存(S3) 取代。原因:

  • S3 也能跑 Spark
  • 不用自建 HDFS 叢集
  • Decoupling 計算與儲存

「Data Lake on S3」(Apache Hudi、Iceberg、Delta Lake)是現在的主流。

Parquet:列式檔案格式#

OLAP 用列式儲存的根本原因:

需求:SELECT SUM(amount) FROM orders WHERE date BETWEEN ... AND ...

行式(傳統 MySQL):
  讀整行(含所有欄位)─ amount 只占 1/30,瀏覽 30x 多資料

列式(Parquet):
  只讀 amount 欄位 ─ I/O 直接是需要量
  + 同欄位資料類型一致 → 壓縮比極高(10x 常見)

Parquet 還有:

  • columnar(按欄存)
  • 內建壓縮(Snappy / Gzip / Zstd)
  • 內建統計(每個 row group 的 min/max → 跳過不相關 group)
  • schema evolution

從 Kafka 拉資料、即時處理、輸出到下游:

Kafka ─→ Flink ─→ ClickHouse / Kafka / DB
              ─→ 計算窗口(5 分鐘 PV、UV)
              ─→ 異常偵測
              ─→ 即時 join

Flink 是業界標準(事件時間、watermark、exactly-once、state management)。Spark Streaming 微批處理較簡單但延遲較高。

# Flink 概念
stream = env.from_source(kafka_source)
stream.window(TumblingEventTimeWindows.of(Time.minutes(5)))
      .aggregate(PV_counter)
      .sink_to(clickhouse_sink)

OLAP 引擎選擇#

當資料已在 lake / DW 裡,怎麼快速查?

引擎特性
ClickHouse列式、極快聚合、寫入也快、分散式 SQL
Druid即時 OLAP、優秀 time-series、聚合預計算
Presto / Trino跨多 source 查詢(S3、Hive、MySQL)
Apache Doris國內常用、MPP 架構
Snowflake商業 SaaS,極簡運維
BigQueryGoogle Cloud,serverless
RedshiftAWS,商業
StarRocksDoris 衍生,性能更激進

電商選型:

  • 即時報表 / 明細查詢:ClickHouse
  • 即時聚合(時序):Druid
  • ad-hoc / 跨源:Trino
  • 雲端託管簡化:BigQuery / Snowflake

ClickHouse 是過去 5 年的明星 ── 對「結構化大規模 OLAP」幾乎是預設選項。

ClickHouse 的核心特色#

  1. 列式 + 高壓縮:1 億行 100 GB → 壓到 5 GB 常見
  2. MergeTree 引擎家族:append-only 寫入 + 後台 merge(LSM 風格)
  3. 分散式表:透明分片 + 副本
  4. 物化視圖(MV):寫入時自動聚合,查詢直接讀預聚合結果
  5. SIMD + JIT:極致 CPU 效率

寫入特性:

  • 寫入要批次(一次數萬行),單行寫慘
  • 不支援高併發點查(每查一次掃 column)
  • 適合 append + 偶爾重寫,不適合頻繁 UPDATE/DELETE

對應的查詢場景#

-- ClickHouse 強項:聚合
SELECT date, brand, SUM(amount), COUNT(DISTINCT user_id)
FROM orders
WHERE date BETWEEN '2025-01-01' AND '2025-04-30'
GROUP BY date, brand
ORDER BY date

-- 1 億行掃描在幾秒內完成
-- ClickHouse 弱項:點查
SELECT * FROM orders WHERE order_id = 'abc123'
-- 慢,因為要掃 column 找該行
-- 解:加 PRIMARY KEY (date, order_id) + 用 date 篩選

寬表 vs 星型 schema#

OLTP 走第三範式(多表 + 外鍵)。OLAP 反範式:

事實表 + 維度表(star schema)
              或
        寬表(denormalized)

寬表把 join 預先做掉、犧牲空間換查詢速度:

CREATE TABLE order_wide (
    order_id, user_id, user_name, user_city, user_age, user_level,
    sku_id, sku_name, brand_name, category_name,
    price, amount, ...
)

ClickHouse 偏好寬表:列式壓縮讓重複資料代價小,查詢時不需要 join。

資料管道全景#

把這章串起來:

                 [WEB / APP]
                      │ 用戶行為
                      ▼
                ┌──────────┐
                │  Kafka   │   ← 短期緩衝(小時級保留)
                └─┬──────┬─┘
                  │      │
        ┌─────────┘      └─────────┐
        ▼                          ▼
  [流處理 Flink]              [批寫 Parquet]
        │                          │
        ▼                          ▼
  ┌──────────┐               ┌──────────┐
  │ClickHouse│               │   S3     │
  │(即時OLAP)              │ (長期lake)│
  └──────────┘               └─┬────────┘
                                │
                                ▼
                          ┌──────────┐
                          │  Trino   │
                          │ Spark    │
                          │ (offline)│
                          └──────────┘

OLTP 系統(MySQL)也透過 binlog → Kafka → ClickHouse 同步明細到 OLAP,達成「線上業務 + 即時分析」雙系統解耦。

小結#

  • OLTP 與 OLAP 是兩個獨立世界,要用對的工具
  • Kafka 是現代資料管道的脊椎:緩衝、解耦、重播
  • HDFS 逐漸被物件儲存取代,PB 級資料 lake 在 S3
  • Parquet 是行業 OLAP 檔案格式
  • 流處理:Flink;批處理:Spark
  • OLAP 引擎:ClickHouse(近年首選)、Druid、Trino
  • 寬表 + 反範式是 OLAP schema 設計的常規

下章看「總結性的選型決策」:給定一個業務問題,怎麼挑儲存。