從 OLTP 到 OLAP#
到此為止本章節談的都是 OLTP(線上交易):訂單、商品、購物車、賬戶。但電商還有大量分析需求:
- 用戶行為日誌(每個點擊、每個瀏覽)
- 推薦系統訓練資料
- BI 報表(銷量、轉化、留存)
- 風控規則計算
- 個性化定價
這些是 OLAP(線上分析),特性:
| 維度 | OLTP | OLAP |
|---|---|---|
| 寫入 | 單筆即時 | 批次或流 |
| 讀取 | 單筆 / 小範圍 | 跨百萬行聚合 |
| 並發 | 高 | 低 |
| 延遲 | < 100ms | 秒到分鐘可接受 |
| 資料模型 | 行式 | 列式 |
| 規模 | TB | PB |
| 一致性 | 強 | 弱(分析可容忍) |
兩個世界用不同儲存、不同思考。
前端埋點之類的「海量原始資料」#
埋點:用戶在 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 4partition 是並行單位 ── 一個 consumer group 最多能有 partition 數的 consumer 並行。
producer 寫入 partition 策略:
- 沒指定 key → round-robin
- 指定 key →
hash(key) % num_partitions,同 key 同 partition(保順序)
Kafka 在電商的典型用法#
| 場景 | topic | producer | consumer |
|---|---|---|---|
| 用戶行為 | user_events | API gateway | 流處理、ML 訓練、ClickHouse |
| 訂單事件 | order_lifecycle | order service | 庫存、支付、配送、分析 |
| 商品變更 | product_updates | product CDC | search index、cache 失效 |
| 計費 / 報表 | billing_events | various | 結算系統 |
| 系統日誌 | app_logs | log shipper | ELK、長期歸檔 |
HDFS:更大的儲存#
Kafka 適合「短期持有 + 流式消費」,但保留 PB 級 / 多年 → 太貴。轉到 HDFS 或物件儲存(S3):
Kafka ──Flink/Spark──→ Parquet files on HDFS / S3HDFS 特性:
- 為大檔(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
流處理:Flink / Spark Streaming#
從 Kafka 拉資料、即時處理、輸出到下游:
Kafka ─→ Flink ─→ ClickHouse / Kafka / DB
─→ 計算窗口(5 分鐘 PV、UV)
─→ 異常偵測
─→ 即時 joinFlink 是業界標準(事件時間、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,極簡運維 |
| BigQuery | Google Cloud,serverless |
| Redshift | AWS,商業 |
| StarRocks | Doris 衍生,性能更激進 |
電商選型:
- 即時報表 / 明細查詢:ClickHouse
- 即時聚合(時序):Druid
- ad-hoc / 跨源:Trino
- 雲端託管簡化:BigQuery / Snowflake
ClickHouse 是過去 5 年的明星 ── 對「結構化大規模 OLAP」幾乎是預設選項。
ClickHouse 的核心特色#
- 列式 + 高壓縮:1 億行 100 GB → 壓到 5 GB 常見
- MergeTree 引擎家族:append-only 寫入 + 後台 merge(LSM 風格)
- 分散式表:透明分片 + 副本
- 物化視圖(MV):寫入時自動聚合,查詢直接讀預聚合結果
- 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 設計的常規
下章看「總結性的選型決策」:給定一個業務問題,怎麼挑儲存。