單機資料庫儲存上限受限於硬體,當資料量從 200 萬激增至 600 萬時,垂直擴展(升級硬體)成本指數級上升。水平擴展採用多台廉價伺服器分攤負載,擴充彈性大、成本可控。
以 ID % N 路由資料至 N 台機器。當新增機器(N→N+1),絕大多數資料的取模結果改變,觸發大規模資料遷移。億級資料遷移耗時數小時至數天,期間來源庫負載飆升,服務極易不可用。
優勢:新增/移除機器時,僅影響鄰近節點的資料,遷移量約為 1/(N+1),大幅降低擴縮容成本。
實體機器較少時,Hash 分布不均會導致熱點。引入虛擬節點(如每台實體機對應 3 個虛擬節點 1a,1b,1c),使節點在環上分布更均勻,資料負載更平衡。
實測 SolrCloud 寫入 20 筆資料需數十秒,效能不符預期。改為自管分片:
業務增長時,可依資料類型(用戶、微博等)劃分獨立叢集,各自套用上述架構。
import hashlib, bisect
class ConsistentHash:
def __init__(self, nodes=None, replicas=100):
self.replicas = replicas
self.ring = {}
self.sorted_keys = []
if nodes:
for node in nodes:
self.add_node(node)
def _hash(self, key):
return int(hashlib.md5(key.encode()).hexdigest(), 16) % (2**32)
def add_node(self, node):
for i in range(self.replicas):
key = self._hash(f"{node}#{i}")
self.ring[key] = node
self.sorted_keys.append(key)
self.sorted_keys.sort()
def get_node(self, key):
if not self.ring: return None
hash_val = self._hash(key)
idx = bisect.bisect(self.sorted_keys, hash_val) % len(self.sorted_keys)
return self.ring[self.sorted_keys[idx]]