01

總覽與定位

當單機儲存與寫入吞吐觸頂時,如何把資料拆到多台機器上?

隨著業務成長,單一資料庫節點遲早會遇到儲存容量、寫入吞吐或索引維護成本的上限。此時我們需要把資料集拆成多個子集,分散到不同節點上各自服務——這就是分片(Sharding / Partitioning)。

分片的核心問題只有一個:給定一筆資料(或查詢),應該路由到哪個 shard? 路由策略決定了擴容難度、查詢效率、熱點風險,以及跨 shard 交易的複雜度。

座標分片 vs 複寫

• 分片(Sharding):把不同資料子集放到不同節點,目的是擴充寫入與儲存容量。
• 複寫(Replication):把相同資料拷貝到多個節點,目的是容錯與擴充讀取吞吐。
Production 大規模系統(Cassandra、Spanner、DynamoDB)幾乎都是兩者結合:每個 shard 本身再有多份 replica。

維度 單機資料庫 分片後
儲存上限 受單機磁碟與索引大小限制 隨 shard 數線性擴展
寫入吞吐 單一 WAL / B-tree 寫入瓶頸 寫入分散到多個 shard owner
查詢複雜度 JOIN、聚合在單機完成 跨 shard 查詢需 scatter-gather 或 denormalize
交易 本地 ACID 天然成立 跨 shard 交易需 2PC / Saga 等分散式協調

分片換來水平擴展能力,代價是路由、一致性與跨 shard 查詢的系統複雜度。

一句話答法分片是把資料集拆成多個子集分散到不同節點,以突破單機儲存與寫入瓶頸;它與複寫互補,是大型資料系統的基礎擴展手段。

02

垂直 vs 水平分片

先釐清「拆欄位」與「拆列」——面試裡常被混用。

垂直分片(Vertical Partitioning)

依欄位或功能域拆分。例如把用戶表的 profile 欄位放到 Profile DB,把 billing 欄位放到 Billing DB;或把圖片、影片等大物件拆到 Object Storage,主表只留 metadata。

  • 優點:各子表可獨立擴展、備份與存取控制;熱欄位與冷欄位可分流。
  • 缺點:跨表 JOIN 變成跨服務 RPC;schema 變更需協調多個 store。
  • 典型場景:微服務邊界、冷熱資料分離、合規隔離(PII 獨立庫)。

水平分片(Horizontal Partitioning / Sharding)

依列(row)拆分:同一 schema 的多筆資料,依 sharding key 路由到不同 shard。例如 user_id 模 4 分到 4 台 DB,或依時間 range 把訂單分到不同 partition。

  • 優點:寫入與儲存可隨 shard 數近乎線性擴展;單 shard 資料量可控。
  • 缺點:需選好 sharding key;跨 shard 查詢與交易成本高。
  • 典型場景:社交 feed、電商訂單、IoT 時序資料、多租戶 SaaS。
陷阱「分表」不一定是 Sharding

MySQL 分表若只是把同一邏輯表拆成 orders_2024、orders_2025 但仍在一台機器上,那是分區(Partitioning)或表管理策略,不是水平擴展。真正的 sharding 意味著不同 partition 由不同節點服務。

一句話答法垂直分片拆欄位/功能域,適合微服務邊界;水平分片拆列,才是突破單機寫入與容量上限的核心手段。

03

三大分片策略

Range、Hash、Directory——路由公式決定擴容與查詢行為。

1. Range-based Sharding

依 sharding key 的連續區間劃分。例如用戶 ID 1..1M → Shard A,1M+1..2M → Shard B;或依時間 2024-01 → Partition Jan。

  • 優點:範圍查詢(時間區間、ID 區間)可只打少數 shard;資料局部性佳,適合時序與報表。
  • 缺點:新用戶或新時間段可能全部擠在「最新 range」→ hot shard;手動調整 range 邊界需 rebalancing。

2. Hash-based Sharding

對 sharding key 做 hash,再映射到 shard。最簡形式是 hash(key) % N(N 為 shard 數)。

  • 優點:key 分布均勻時負載平衡佳;新增 key 自然打散。
  • 缺點:N 改變時幾乎所有 key 需 remap(見一致性雜湊手冊);無法做 key 範圍查詢,只能 point lookup。

3. Directory / Lookup Sharding

維護一張路由表(shard map):tenant_id → shard_id 或 user_id → shard_id,由 control plane 或 metadata service 管理。

  • 優點:彈性最高——可手動遷移大 tenant、做 canary、A/B 分 shard;不受 hash 公式限制。
  • 缺點:路由表本身成為關鍵依賴與一致性挑戰;每次請求多一次 lookup(通常 cache)。
策略 路由方式 負載平衡 範圍查詢 擴容難度
Range key 落在哪個 interval 易受 skew 影響 友好 需 split range、搬資料
Hash hash(key) % N 或 hash ring 均勻(key 隨機時) 不支援 Modulo 全量 remap;Consistent Hash 局部
Directory 查 shard map 可人工調整 取決於 map 設計 改 map + 背景遷移

沒有銀彈:Range 適合時序與報表;Hash 適合均勻 point lookup;Directory 適合多租戶與需人工調度的場景。

延伸進階 Hash 路由

當 shard 數會動態變化時,單純 % N 代價過高。Production 常用 Consistent Hashing、Rendezvous Hashing 或 Dynamo-style 虛擬節點,把 remap 限制在局部區間——詳見本手冊「一致性雜湊綜合手冊」。

一句話答法Range 靠區間、Hash 靠公式、Directory 靠路由表;選策略時先問「查詢是 point 還是 range?shard 數會不會常變?有沒有 hot tenant?」

04

分片帶來的系統挑戰

Hot key、跨 shard 查詢、Rebalance——分片後才會浮現的問題。

選對 Sharding Key

Sharding key 應具備:高基數(避免全擠同一 shard)、查詢局部性(多數請求只需單 shard)、寫入分散(避免 sequential ID 全落最新 range)。

反例:用 country_code 做 key,大國流量會打爆單 shard;用 monotonic auto_increment 做 range sharding,新資料永遠寫入最後一個 partition。

Hot Spot(熱點)

即使 hash 均勻,單一 key 或少量 key 流量過大仍會打爆所在 shard(celebrity 貼文、搶購 SKU、全局 counter)。緩解手段包括:local cache、read replica fanout、key 拆分子 key、非同步聚合、寫入 queue 削峰。

跨 Shard 查詢與聚合

若查詢無法由 sharding key 定位單 shard,gateway 需scatter-gather:並行查所有 shard 再合併結果。成本高、延遲大,因此設計時常反規範化或建全域二級索引(如 Elasticsearch)承擔跨 shard 搜尋。

Rebalancing 與線上遷移

新增 shard、split hot range、遷移大 tenant 都需要背景搬資料。Production 流程通常包含:雙寫、追 incremental change、驗證、切流量、下線舊副本——並全程節流,避免搬遷與線上流量互搶 I/O。

陷阱跨 Shard 交易不是「加個分布式鎖」就完事

若一筆交易涉及兩個 shard 上的列,本地 ACID 不再成立。需引入 2PC、Saga、或重新設計資料模型讓相關列共 shard(例如把 order 與 order_items 都用 order_id 做 sharding key)。

一句話答法分片後要面對 sharding key 選型、hot spot、scatter-gather 與 rebalance;最好在一開始就讓大部分請求落在單 shard,並預留背景遷移能力。

05

互動 Demo:分片路由模擬器

同一組 key,切換 Range 與 Hash 策略,觀察路由結果與 hot shard 差異。

下方模擬器有 4 個 shard(A–D)與 12 筆 sample key。切換策略後可看到每個 key 落在哪個 shard;Range 模式刻意模擬「新 key 集中在最新區間」造成的 skew,Hash 模式則展示較均勻的分布。

互動 · 分片路由模擬器 切換 Range / Hash 策略
空閒 shard 正常負載 偏高 Hot shard
Range:key 依 ID 區間路由;最新區間(Shard D)承接連續新 ID,易形成 hot spot。
Key Sharding Key 目標 Shard 備註

洞察:Range 適合區間查詢但需防 skew;Hash 分散寫入但失去 range scan 能力——選型取決於存取模式而非公式優雅度。

一句話答法Demo 展示了同一批 key 在 Range 與 Hash 下的不同落點;面試時應能說出為何 Twitter 早期用 snowflake + hash,而時序日誌常用 time-range partition。

06

面試考點與架構折衷

高頻追問:怎麼選 sharding key?怎麼擴容?跨 shard 怎麼查?

考點 1如何選擇 Sharding Key?

回答框架:
1. 列出主要存取模式(point lookup vs range scan vs 聚合)。
2. 選高基數、與查詢條件對齊的 key(如 messaging 用 conversation_id,電商用 user_id 或 order_id)。
3. 說明如何避免 hot spot(hash 子 key、local cache、異步 counter)。
4. 若需跨實體 JOIN,說明 co-location 或 denormalize 策略。

考點 2Shard 從 4 台擴到 8 台怎麼做?

回答框架:
1. 若用 % N:幾乎全量 remap → 說明為何改用 Consistent Hashing 或 double-write 遷移。
2. 若用 Consistent Hashing:只搬相鄰 range,背景 backfill + 節流。
3. 若用 Directory:更新 shard map,雙寫 + 驗證 + 切流量。
4. 強調零 downtime需要 ring version / map version 與 client 相容窗口。

場景 建議策略 理由
多租戶 SaaS(大 tenant 需獨立遷移) Directory + 必要時專用 shard 可手動把 VIP tenant 搬到獨立節點
社交訊息 / 用戶資料 Hash(user_id) 或 Consistent Hash Point lookup 為主,需均勻寫入
日誌 / 指標 / 時序 Range by time 範圍查詢與 TTL 刪除舊 partition 天然契合
電商訂單(依用戶查歷史) Hash(user_id) 同一用戶訂單共 shard,避免 scatter-gather
風險過早分片

在流量尚未觸頂前引入 sharding,會過早承擔路由、遷移與跨 shard 一致性成本。實務上常先垂直擴展 + 讀 replica + cache,確認單機瓶頸後再水平分片,並保留 rebalance 與 observability 預算。

一句話答法高分答案 = 正確的 sharding key + 匹配存取模式的策略(Range/Hash/Directory)+ 擴容遷移流程 + 對 hot spot 與跨 shard 查詢的具體緩解。