"Shard" 英文原意為「碎片」,作為資料庫技術術語,最早見於大型多人線上角色扮演遊戲(MMORPG)架構中。業界通稱 "Sharding" 為「分片」。這並非一項新技術,而是一種相對樸素的軟體設計理念。在 MySQL 5.0 引入資料表分區功能之前,許多潛在用戶對 MySQL 的擴展性存疑,分區能力一度成為衡量資料庫可擴展性的關鍵指標(雖非唯一)。
Sharding 並非某個特定資料庫軟體的附屬功能,而是建立在具體技術細節之上的抽象處理層,屬於水平擴展的解決方案。其核心目的是突破單節點資料庫伺服器的 I/O 能力瓶頸,解決資料庫擴展性難題。
商業資料庫(如 Oracle RAC)多採用共享儲存機制,對於 I/O 密集型應用,瓶頸易落於儲存層,導致後續擴容只能採用 Scale Up(向上擴展),硬體成本、開發維護門檻均較高。相比之下,Sharding 基本針對開源資料庫,業界趨勢明顯轉向擁抱 Scale Out(向外擴展),逐漸從 Scale Up 的束縛中釋放。
並非所有場景都適合 Sharding。線上遊戲、即時通訊(IM)、部落格服務提供商(BSP)等場景較為適配,其共性在於:抽象出的資料物件間關聯極小。以 IM 為例,每位用戶可抽象為獨立資料物件,完全可獨立儲存於任意節點,實現「Share Nothing」架構;部落格站點的用戶生成內容(UGC)同理,不同用戶資料可隔離至不同儲存集合,對用戶透明。
然而,若資料粒度間非「Share Nothing」(如交易記錄同時包含買賣雙方資訊),隨時間推移,買賣家資料分散至不同 Shard,跨分片查詢開銷劇增。Sharding 並非銀彈,處理事務型應用極複雜,跨資料庫事務難以保證完整性,採用何種形式需結合業務實際,切忌生搬硬套。
雖常被等同於水平分區,但二者有本質差異:資料庫分區屬資料物件級操作(表、索引分區),仍在單一資料庫範圍內;Sharding 則能跨資料庫、甚至跨物理機器。Sharding 思想源於分區,卻超越了單機邊界。

策略選擇多樣:基於表、ID 範圍、時間、SOA 服務劃分等。與傳統分區不同,Sharding 與業務結合極緊密,成功關鍵在於對業務的深度理解與可行性分析,核心原則是「業務邏輯驅動」。
作為 Web 2.0 代表站點,Digg.com 用戶龐大但資料量非海量(主資料約 30GB),採用 MySQL 5.x,I/O 壓力極大且讀請求佔 98%。針對新聞類資料「近期熱門、舊聞鮮少訪問」的特點,Digg 依時間範圍分片,將不足 10% 的「熱數據」隔離並配置優質硬體,其餘 90% 歸檔存儲。此策略有效平衡成本與體驗,達到預期效果。
基於 Lua 腳本的代理層方案,MySQL Proxy 介於客戶端與伺服器間,提供查詢分析、故障切換、過濾重寫等功能;HSCALE 作為其插件簡化分片流程。雖引入額外開銷,但仍低於集中式處理的單查詢成本。
Google 貢獻專案,源自其財務系統分片實踐。框架層實現帶來優勢:標準 Hibernate 程式模型、低技術門檻、彈性分片策略、虛擬分片支持。
源自人員搜尋網站 Spock 實際需求,基於 MySQL Proxy 分支,提供基於範圍的分片機制,採用 Rails 構建,適合 RoR 技術棧團隊。
Java 生態實現,背後有商業公司支撐,提供企業級支持選項。
針對 PostgreSQL,設計參考 Teradata Hash 機制,資料分布對客戶端透明,充當「資料總線」角色。擴容僅需增加 PL/Proxy 節點。知名應用案例:Skype。
Python 方案,目標包含 Re-balancing(再平衡)功能,較激進,目前僅支援 MySQL。
Sharding 是一項在高速發展中成熟的「老」技術。隨 Web 2.0 演進,Sharding 從虛化概念轉為具體落地思路,開源浪潮注入新活力。未來將有更多專案採用,更多成熟方案涌現。你的站點,Sharding 了嗎?
--EOF--
註:本週末筆者將參加「體驗基於 OpenSolaris 的 Web/企業應用」活動,分享《設計可擴展的面向互聯網應用的 MySQL 資料庫》,歡迎杭州朋友光臨指導。