開源數據庫Sharding技術

從Shard到Shardinghtml

"Shard" 這個詞英文的意思是"碎片",而做爲數據庫相關的技術用語,彷佛最先見於大型多人在線角色扮演遊戲(MMORPG)中。"Sharding" 姑且稱之爲"分片"。mysql

Sharding 不是一門新技術,而是一個相對簡樸的軟件理念。如您所知,MySQL 5以後纔有了數據表分區功能,那麼在此以前,不少MySQL的潛在用戶都對 MySQL 的擴展性有所顧慮,而是否具有分區功能就成了衡量一個數據庫可擴展性與否的一個關鍵指標(固然不是惟一指標)。數據庫擴展性是一個永恆的話題,MySQL 的推廣者常常會被問到:如在單一數據庫上處理應用數據捉襟見肘而須要進行分區化之類的處理,是如何辦到的呢? 答案是:Sharding。sql

Sharding不是一個某個特定數據庫軟件附屬的功能,而是在具體技術細節之上的抽象處理,是水平擴展(Scale Out,亦或橫向擴展、向外擴展)的解決方案,其主要目的是爲突破單節點數據庫服務器的I/O能力限制,解決數據庫擴展性問題。數據庫

事關數據庫擴展性編程

提及數據庫擴展性,這是個很是大的話題。目前的商業數據都有本身的擴展性解決方案,在過去相對來講比較成熟,可是隨着互聯網的高速發展,不可避免的會帶來一些計算模式上的演變,這樣不少主流商業系統也不免暴露出一些不足之處。好比 Oracle的RAC是採用共享存儲機制,對於I/O密集型的應用,瓶頸很容易落在存儲上,這樣的機制決定後續擴容只能是Scale Up(向上擴展) 類型,對於硬件成本、開發人員的要求、維護成本都相對比較高。服務器

Sharding基本上是針對開源數據庫的擴展性解決方案,不多有據說商業數據庫進行Sharding 的。目前業界的趨勢基本上是擁抱Scale Out,逐漸從Scale Up中解放出來。框架

Sharding的應用場景分佈式

任何技術都是在合適的場合下能發揮應有的做用。 Sharding也同樣。聯機遊戲、IM、BSP都是比較適合 Sharding 的應用場景。其共性是抽象出來的數據對象之間的關聯數據很小。好比IM ,每一個用戶若是抽象成一個數據對象,徹底能夠獨立存儲在任何一個地方,數據對象是 Share Nothing 的;再好比 Blog 服務提供商的站點內容,基本爲用戶生成內容(UGC),徹底能夠把不一樣的用戶隔離到不一樣的存儲集合,而對用戶來講是透明的。ide

這個"Share Nothing"是從數據庫集羣中借用的概念,舉例來講,有些類型的數據粒度之間就不是"Share Nothing" 的,好比相似交易記錄的歷史表信息,若是一條記錄中既包含賣家信息與買家信息,若是隨着時間推移,買、賣家會分別與其它用戶繼續進行交易,這樣不可避免的兩個買賣家的信息會分佈到不一樣的Sharding DB上,而這時若是針對買賣家查詢,就會跨越更多的 Sharding,開銷就會比較大。工具

Sharding並非數據庫擴展方案的銀彈,也有其不適合的場景,好比處理事務型的應用就會很是複雜。對於跨不一樣DB的事務,很難保證完整性,得不償失。因此,採用什麼樣的 Sharding 形式,不是生搬硬套的。

Sharding與數據庫分區(Partition)的區別

有的時候,Sharding也被近似等同於水平分區(Horizontal Partitioning),網上不少地方也用 水平分區來指代Sharding,但我我的認爲兩者之間實際上仍是有區別的。的確,Sharding 的思想是從分區的思想而來,但數據庫分區基本上是數據對象級別的處理,好比表和索引的分區,每一個子數據集上可以有不一樣的物理存儲屬性,仍是單個數據庫範圍內的操做,而Sharding是可以跨數據庫,甚至跨越物理機器的。(見對比表格)

Sharding策略

數據 Sharding 的策略與分區表的方式有不少相似的地方,有基於表、ID範圍、數據產生的時間或是SOA 下理念下的基於服務等衆多方式可選擇。而與傳統的表分區方式不一樣的是,Sharding 策略和業務結合的更爲緊密,成功的Sharding必須對本身的業務足夠熟悉,進行衆多可行性分析的基礎上進行,"業務邏輯驅動"。

Sharding實現案例分析:Digg 網站

做爲風頭正勁的 Web 2.0網站之一的Digg.com,雖然用戶羣龐大,但網站數據庫數據並不是海量,去年同期主數據大約只有30GB的樣子,如今應該更大一些,但應該不會出現數量級上增加,數據庫軟件採用 MySQL 5.x。Digg.com的IO壓力很是大,並且是讀集中的應用(98%的IO是讀請求)。由於提供的是新聞類服務,這類數據有其自身特色,最近時間段的數據每每是讀壓力最大的部分。

根據業務特色,Digg.com根據時間範圍對主要的業務數據作Sharding,把不到10%的"熱"數據有效隔離開來,同時對這部分數據用以更好的硬件,提供更好的用戶體驗。而另外90%的數據因用戶不多訪問,因此儘管訪問速度稍慢一點,對用戶來講,影響也很小。經過Sharding,Digg 達到了預期效果。

現有的Sharding軟件簡介

如今Sharding相關的軟件實現其實很多,基於數據庫層、DAO層、不一樣語言下也都不乏案例。限於篇幅,做一下簡要的介紹。

MySQL Proxy + HSCALE

一套比較有潛力的方案。其中MySQL Proxy (http://forge.mysql.com/wiki/MySQL_Proxy) 是用Lua腳本實現的,介於客戶端與服務器端之間,扮演Proxy的角色,提供查詢分析、失敗接管、查詢過濾、調整等功能。目前的0.6版本還作不到讀、寫分離。HSCALE則是針對MySQL Proxy 插件,也是用Lua實現的,對Sharding過程簡化了許多。須要指出的是,MySQL Proxy與HSCALE 各自會帶來必定的開銷,但這個開銷與集中式數據處理方式單條查詢的開銷仍是要小的。

Hibernate Shards

這是Google技術團隊貢獻的項目(http://www.hibernate.org/414.html),該項目是在對 Google財務系統數據Sharding過程當中誕生的。由於是在框架層實現的,因此有其獨特的特性:標準的Hibernate編程模型,會用Hibernate就能搞定,技術成本較低;相對彈性的Sharding策略以及支持虛擬Shard等。

Spock Proxy

這也是在實際需求中產生的一個開源項目。Spock(http://www.spock.com/)是一我的員查找的Web 2.0網站。經過對本身的單一DB進行有效 Sharding化 而產生了Spock Proxy(http://spockproxy.sourceforge.net/ ) 項目,Spock Proxy算得上MySQL Proxy的一個分支,提供基於範圍的 Sharding 機制。Spock是基於Rails的,因此Spock Proxy也是基於Rails構建,關注RoR的朋友不該錯過這個項目。

HiveDB

上面介紹了RoR的實現,HiveDB (http://www.hivedb.org/)則是基於Java的實現,另外,稍有不一樣的是,這個項目背後有商業公司支持。

PL/Proxy

前面幾個都是針對MySQL的 Sharding 方案,PL/Proxy則是針對PostgreSQL的,設計思想相似 Teradata的Hash機制,數據存儲對客戶端是透明的,客戶請求發送到PL/Proxy後,由這裏分佈式存儲過程調用,統一分發。PL/Proxy的設計初衷就是在這一層充當"數據總線"的職責,因此,當數據吞吐量支撐不住的時候,只須要增長更多的PL/Proxy服務器便可。大名鼎鼎的 Skype 用的就是PL/Proxy的解決方案。

Pyshards

http://code.google.com/p/pyshards/wiki/Pyshards 這是個基於Python的解決方案。該工具的設計目標還有個Re-balancing在裏面,這卻是個比較激進的想法。目前只支持MySQL數據庫。

相關文章
相關標籤/搜索