快轉到主要內容
  1. Core/

Consistent Hashing|分散式系統的水平擴展關鍵

Idle Engineer
作者
Idle Engineer
AI Runs. I Nap. | 404 Career Not Found
目錄

TL;DR | 面試情境模擬
#

👴 面試官:什麼是 Consistent Hashing?解決了什麼問題?

🧑‍💻 :傳統 Hash 分配(key % N)在增減節點時,幾乎所有 key 都要重新分配,對資料庫或 Cache 是災難。Consistent Hashing 把所有節點和 key 都映射到一個 0 到 2^32 的環上,每個 key 順時針找到最近的節點。增減一個節點時,只有這個節點附近的 key 需要搬移,其他資料不受影響。


為什麼普通 Hash 不夠用
#

假設有 3 台 Cache Server,用 key % 3 決定存哪台:

key "user:1" → hash 101 → 101 % 3 = 2 → Server 2
key "user:2" → hash 102 → 102 % 3 = 0 → Server 0

現在加一台 Server,變成 key % 4

key "user:1" → hash 101 → 101 % 4 = 1 → Server 1  ← 換了!
key "user:2" → hash 102 → 102 % 4 = 2 → Server 2  ← 換了!

問題:幾乎每個 key 都換了位置,舊的 Cache 全部 Miss,所有請求直打資料庫 → Cache Stampede(雪崩)。


Consistent Hashing:Hash Ring
#

把所有可能的 Hash 值排成一個環(0 到 2^32-1),節點和 key 都映射到環上的位置:

                  0
           Server A (100)
        ╱                ╲
  3000               500
    │                   │
  Server C (2800)    Server B (700)
        ╲                ╱
                2500

查找規則:每個 key 對應的值,順時針方向找到的第一個節點,就是它的目標。

加入新節點
#

加入 Server D (1200)

原本:hash 值在 700-2800 之間的 key 都在 Server C
加入後:700-1200 的 key 移到 Server D,其餘不變

只有一小段 key 需要搬移

虛擬節點(Virtual Nodes)
#

問題:節點數量少時,每個節點的負載可能不均衡(有的節點管的範圍特別大)。

解法:每個實體節點在環上放多個虛擬節點(例如 150 個),讓負載更平均分散。

Server A → A-1, A-2, A-3, ..., A-150(散布在環的各個位置)
Server B → B-1, B-2, B-3, ..., B-150

Cassandra、Amazon DynamoDB 都用了虛擬節點。


💡 面試官可能會追問
#

Q1:Consistent Hashing 用在哪些地方?
#

  • 分散式 Cache:Memcached、Redis Cluster
  • CDN:決定哪台邊緣節點快取這個資源
  • 負載均衡 (Load Balancer):讓同一個 client 的請求路由到同一台 Server(Sticky Session)
  • 分散式資料庫:Cassandra、DynamoDB 的資料分片

Q2:Consistent Hashing 能完全解決資料不均衡嗎?
#

不完全。即使有虛擬節點,如果某個節點的資料特別「熱」(Hot Key),依然會有熱點問題。需要額外的解法,例如:在 Hot Key 後面加隨機後綴分散到多個節點、讀取時加本地 Cache 等。

Q3:節點 Crash 後資料怎麼辦?
#

這是 Consistent Hashing 本身不解決的問題,需要搭配副本機制(Replication)。每個資料在環上順時針存到 N 個節點(例如 N=3),一台 Crash 了,其他副本可以繼續服務。