資料庫 sharding 是一種策略,可解決應用程式資料量過大時的擴充性問題。也就是將單一大型邏輯資料集分割成較小、更易於管理的部分,稱為 shard。每個 shard 都儲存在獨立的資料庫伺服器執行個體,有效將資料和工作負載分散到多部機器。
sharding 是資源調度 (水平擴展) 的重要方法。sharding 可讓您在叢集中新增更多商用伺服器,而不必升級單一伺服器,增加 CPU 或 RAM (垂直擴充),最終達到硬體上限。應用程式可處理幾乎無限成長的資料量和使用者流量。
sharding 是水平擴展的有效做法,同時也是三種常見的水平資源調度策略之一:
資料庫 sharding 是根據稱為 shard 鍵的特定值,將資料分組。shard 鍵是資料庫中的資料欄,例如使用者 ID、客戶區域或訂單編號,可決定特定資料列要儲存在哪個伺服器。當資料寫入資料庫時,系統會查看這個鍵,以決定資料所屬的位置。
為了日後能找到資料,系統必須將查詢導向正確位置。這類轉送作業主要有兩種做法:
資料庫只會鎖定相關資料 shard,因此能更快回覆查詢,並處理數千個並行要求,不會降低速度。

不同應用程式需要不同的資料分割邏輯。您選擇的方法會決定「轉送層」如何尋找資料。
這個方法會對 shard 鍵使用數學公式 (雜湊函式) 來指派資料。舉例來說,系統可能會計算使用者 ID (mod 4),將使用者指派給 4 部伺服器中的 1 部。
雖然雜湊函式有助於一致地分配資料,但只有在 shard 鍵具高基數和低頻率偏差時,才能確保均勻分配。如果選擇的 shard 鍵值很常見,例如「Last Name」中「Smith」出現的次數比「Pyne」多 1,000 次,雜湊函式就會將所有「Smith」記錄傳送至同一個 shard。即使使用數學公式,仍會建立「熱 shard」。
此外,由於公式會變更,這通常需要「重新分割」或在新的伺服器叢集間移動資料,因此採用這種方法時,新增伺服器也很困難。
系統會根據值範圍,指派資料。舉例來說,您可以將使用者 ID 1 到 1,000 放在伺服器 A,並將 1,001 到 2,000 放在伺服器 B。這項功能非常直覺,適合用於需要讀取一系列資料的查詢 (範圍查詢)。但這種做法的缺點是會產生「熱點」,也就是說,如果所有新使用者都指派給伺服器 B,該伺服器就會負責所有工作,而伺服器 A 則閒置。
這項策略會使用對照表 (目錄) 追蹤哪個 shard 包含哪些資料。這種做法最彈性,因為您可以在 shard 之間移動資料,不必變更公式。不過,這個對照表會成為瓶頸,因為每個查詢都必須先檢查目錄,所以會增加延遲。如果目錄發生故障,就會無法存取整個資料庫。
地理 sharding 會根據使用者的實際位置,將資料指派給特定伺服器。舉例來說,法國使用者的資料會儲存在歐盟地區的伺服器,而美國使用者的資料則會儲存在北美地區的伺服器。這可為使用者大幅縮短延遲時間 (速度),並協助公司遵守 GDPR 等資料落地法規。
有時稱為功能分區,這種做法是依據特徵而非資料列來分割資料。舉例來說,您可以將所有「使用者個人資料」資料表放在伺服器 A,並將所有「相片上傳」資料表放在伺服器 B。雖然這種做法能以邏輯方式整理資料,但功能上與微服務資料架構類似,如果特定功能 (例如相簿) 的資料量過大,單一伺服器就無法負荷,並不能解決問題。
選擇合適的 shard 鍵,是 sharding 作業中最關鍵的決定。如果選擇不當的鍵,可能會導致資料分配不均 (熱點),而選擇適當的鍵則可確保所有伺服器平均運作。如要最佳化這項作業,必須考量三個因素:
雖然這兩個詞彙在系統設計中經常一起使用,但解決的問題不同。
sharding 是一種水平分區,會將資料分配到完全不同的伺服器。由於不同伺服器可以同時處理寫入作業,因此能解決硬體容量限制 (儲存空間) 和寫入處理量瓶頸。
分區是將大型資料表分割成較小、更易於管理的部分 (例如按月分割記錄資料表),但這些部分仍保留在同一個伺服器執行個體。這樣一來,您就能輕鬆封存或刪除舊資料,而不影響資料表中的其他內容,解決儲存空間問題。但無法解決伺服器問題。由於所有分區仍位於同一部機器,因此會繼續共用相同的 CPU 和 RAM,這表示如果伺服器達到效能上限,即使是分區也沒有幫助。
複製是指將整個資料庫複製到多部伺服器。如果想確保讀取作業的可用性,這會是不錯的選擇,因為當一個伺服器故障時,另一個伺服器可以接管。不過,由於寫入的每筆資料都必須複製到每個副本,因此寫入速度會受限於單一機器的容量,對於調度寫入資源沒有幫助。
同樣重要的是,大多數複製模型一次只允許一個「寫入者」(主要節點)。如果嘗試讓多部伺服器同時接受寫入作業,可能會發生寫入衝突,也就是兩部伺服器嘗試以不同資訊更新同一筆記錄。解決這些衝突在技術上相當困難,如果沒有由複雜的分散式系統處理,可能會導致資料遺失或不一致。
Spanner 等分散式資料庫具備 sharding 的優勢,並能免除手動作業。這些系統從一開始就設計成可跨機器叢集運作。這些系統會自動處理資料分布、重新平衡,並以公開透明的方式處理複製作業。其中有些系統有多個寫入者,並會自動處理寫入衝突。這可讓您水平擴充,同時維持傳統關聯式資料庫的一致性。
請參閱下表,瞭解這些核心資料庫概念的差異。
功能 | 資料分割 | 分區 | 複製 | 分散式資料庫 |
主要目標 | 大規模調度寫入資源和儲存空間 | 易於管理與維護 | 高可用性和調度讀取資源 | 自動化全球資源調度 |
資料位置 | 不同伺服器上的不同資料區塊 | 同一部伺服器上的不同資料區塊 | 相同資料在多部伺服器上的多個副本 | 在叢集中管理 |
寫入效能 | 大幅改善 (平行寫入) | 小幅改善 (較小的索引) | 無改善 (寫入作業必須傳送至所有副本) | 大幅改善 |
複雜度 | 高 | 中 | 低 | 低 (代管) |
功能
資料分割
分區
複製
分散式資料庫
主要目標
大規模調度寫入資源和儲存空間
易於管理與維護
高可用性和調度讀取資源
自動化全球資源調度
資料位置
不同伺服器上的不同資料區塊
同一部伺服器上的不同資料區塊
相同資料在多部伺服器上的多個副本
在叢集中管理
寫入效能
大幅改善 (平行寫入)
小幅改善 (較小的索引)
無改善 (寫入作業必須傳送至所有副本)
大幅改善
複雜度
高
中
低
低 (代管)
對於處理 TB 規模的資料或每秒數百萬筆交易的應用程式,sharding 通常是唯一可行的解決方案。
水平資源調度
sharding 可將標準伺服器新增至叢集,實現近乎無限的擴充性。這可避免傳統垂直擴充應用程式的「硬體稅」。如果不採用 sharding,通常就得購買昂貴的專用硬體,但效能仍有上限。sharding 可使用更經濟實惠的機器,讓資料庫隨著業務成長而擴充
提升查詢效能
sharding 可加快個別查詢速度,因為每個伺服器搜尋的資料集較小。查詢作業不必搜尋 1 億列的索引,可能只要搜尋 100 萬列的 shard 即可。此外,由於資料位於不同機器上,因此您可以平行執行多個查詢,大幅提高應用程式的總處理量。
可靠性
sharding 可限制故障的「影響範圍」。如果一個 shard 故障,只有該 shard 的使用者會受到影響,應用程式的其餘部分仍會保持連線。不過,伺服器數量越多,管理負擔就越重。與單一伺服器設定相比,管理數十個執行個體的備份、安全性和修補程式會增加作業複雜度。
sharding 雖然能滿足大規模需求,但會帶來重大的技術和營運取捨。在捨棄單一執行個體架構前,請先考量這些挑戰。
Google Cloud 提供資料庫解決方案,可免除手動 sharding 的繁重工作,讓您專心建構應用程式,不必費心管理基礎架構。


