key-range sharding 用順序換熱點,hash 用均勻換範圍查詢
分片(sharding)只要決定一件事:這筆資料該去哪一台機器。 兩種答案,各自換掉一樣東西。
key-range:按 key 的區間切
key A–F → 節點 1
key G–M → 節點 2
key N–Z → 節點 3
- ✅ 範圍查詢快:「找 09-01 到 09-07 的資料」落在相鄰區間,只問 1~2 台
- ✅ 保有順序,可以做排序掃描
- ❌ 熱點(hotspot)——致命傷
熱點長什麼樣:key 若是時間戳或自增 ID,所有新資料的 key 都在最大的那一端:
節點 1(A–F):閒置
節點 2(G–M):閒置
節點 3(N–Z):100% 忙 ← 全部寫入都打在這台
買了三台,只有一台在工作。
hash:把 key 打散
hash(key) % N → 決定去哪台
- ✅ 分佈均勻,相鄰 key 被打到不同節點,沒有熱點
- ❌ 範圍查詢爛:順序被打散,找一個區間必須問遍所有節點再合併(scatter-gather)
- ❌ 加節點很痛:
% 3變% 4,幾乎所有 key 的歸屬都變 → 標準解法是 consistent hashing + 虛擬節點,讓加減節點只搬動一小部分
對照實際產品
| 產品 | 用哪種 | 後果 |
|---|---|---|
| Big Table | key-range(row key 有序) | 適合掃區間,但要自己設計 row key 避開熱點 |
| DynamoDB | hash(partition key) | 分佈均勻,但跨 partition 查詢很貴 |
判準
你的查詢是「找一個」還是「找一段」。
找一個 → hash;找一段 → key-range,然後想辦法讓 key 不要單調遞增(例如前面加隨機前綴或裝置 ID)。
注意一個容易忽略的後果:分片之後,沒有打中 shard key 的查詢反而更慢了——它要問遍所有節點。這和 垂直擴展換機器,水平擴展換複雜度 說的「複雜度就是代價」是同一件事。