什么是sharding
Sharding的基本思想就要把一個數據庫切分成多個部分放到不同的數據庫 (server)上,從而緩解單一數據庫的性能問題。不太嚴格的講,對於海量數據的數據庫,如果是因為表多而數據多,這時候適合使用垂直切分,即把關系緊密(比如同一模塊)的表切分出來放在一個server上。如果表並不多,但每張表的數據非常多,這時候適合水平切分,即把表的數據按某種規則(比如按ID 散列)切分到多個數據庫(server)上。當然,現實中更多是這兩種情況混雜在一起,這時候需要根據實際情況做出選擇,也可能會綜合使用垂直與水平切分,從而將原有數據庫切分成類似矩陣一樣可以無限擴充的數據庫(server)陣列。
什么是切分
數據庫切分 是一個固有的關系流程,可以通過一些邏輯數據塊將一個表的行分為不同的小組。例如,如果您正在根據時間戳對一個名為 foo 的超大型表進行分區,2010 年 8 月之前的所有數據都將進入分區 A,而之后的數據則全部進入分區 B。分區可以加快讀寫速度,因為它們的目標是單獨分區中的較小型數據集。
分區功能並不總是可用的(MySQL 直到 5.1 版本后才支持),而且其需要的商業系統的成本也讓人望而卻步。更重要的是,大部分分區實現在同一個物理機上存儲數據,所以受到硬件基礎的影響。除此之外,分區也不能鑒別硬件的可靠性或者說缺乏可靠性。因此,很多智慧的人們開始尋找進行伸縮的新方法。
切分 實質上是數據庫級別的分區:它不是通過數據塊分割數據表的行,而是通過一些邏輯數據元素對數據庫本身進行分割(通常跨不同的計算機)。也就是說,切分不是將數據表 分割成小塊,而是將整個數據庫 分割成小塊。
切分的一個典型示例是基於根據區域對一個存儲世界范圍客戶數據的大型數據庫進行分割:切分 A 用於存儲美國的客戶信息,切分 B 用戶存儲亞洲的客戶信息,切分 C 歐洲,等。這些切分分別處於不同的計算機上,且每個切分將存儲所有相關數據,如客戶喜好或訂購歷史。
切分的好處(如分區一樣)在於它可以壓縮大型數據:單獨的數據表在每個切分中相對較小,這樣就可以支持更快速的讀寫速度,從而提高性能。切分還可以改善可靠性,因為即便一個切分意外失效,其他切分仍然可以服務數據。而且因為切分是在應用程序層面進行的,您可以對不支持常規分區的數據庫進行切分處理。資金成本較低同樣也是一個潛在優勢。
垂直拆分
垂直切分的最大特點就是規則簡單,實施也更為方便,尤其適合各業務之間的耦合度非常低,相互影響很小,業務邏輯非常清晰的系統。在這種系統中,可以很容易做到將不同業務模塊所使用的表分拆到不同的數據庫中。根據不同的表來進行拆分,對應用程序的影響也更小,拆分規則也會比較簡單清晰。
水平拆分
水平切分於垂直切分相比,相對來說稍微復雜一些。因為要將同一個表中的不同數據拆分到不同的數據庫中,對於應用程序來說,拆分規則本身就較根據表名來拆分更為復雜,后期的數據維護也會更為復雜一些。
兩種拆分組合
讓我們從普遍的情況來考慮數據的切分:一方面,一個庫的所有表通常不可能由某一張表全部串聯起來,這句話暗含的意思是,水平切分幾乎都是針對一小搓一小搓(實際上就是垂直切分出來的塊)關系緊密的表進行的,而不可能是針對所有表進行的。另一方面,一些負載非常高的系統,即使僅僅只是單個表都無法通過單台數據庫主機來承擔其負載,這意味着單單是垂直切分也不能完全解決問明。因此多數系統會將垂直切分和水平切分聯合使用,先對系統做垂直切分,再針對每一小搓表的情況選擇性地做水平切分。從而將整個數據庫切分成一個分布式矩陣。
hibernate shards
hibernate的shards方案:
這里有幾篇文章可以參考一下:
Hibernate Shards 數據的水平、垂直切割(一)- Hibernate測試環境
Hibernate Shards 數據的水平、垂直切割(二)- Hibernate Shards基本演示
Hibernate Shards 數據的水平、垂直切割(三)- Hibernate Shards結構
注意:Hibernate Shards是不支持跨切分查詢的。
使用hibernate shards進行拆分:
http://www.ibm.com/developerworks/cn/java/j-javadev2-11/index.html
也可以用hibernate shards構建基於SAAS的應用,因為我們知道在SAAS應用中,數據是需要隔離的,現在的隔離有很多種方案:
比如在IAAS建立虛擬化的完全隔離。
在PAAS基於策略的隔離等。
下面這篇是數據隔離的一個示例:
http://www.oschina.net/question/12_12465
apache slice
Slice擴展自OpenJPA用於分布式數據庫的一個開源項目。Slice以插件的方式附加至OpenJPA runtime,通過配置一個持久單元就能夠激活多個數據庫支持。一旦配置好Slice,現有OpenJPA應用程序就能夠在同一個事務中利用多個數據庫進行處理。查詢也將依賴所有數據庫並行執行,任何更新也會提交至相應的數據庫。
更確切的說slice更像是openjpa的一個插件,用來實現shards,下面看一下官方的圖
如果使用openjpa的方案可以考慮一下。
順便附一下官方的網址:
http://people.apache.org/~ppoddar/slice/site/
dbShards
首先,這個是一個商用的產品,絕對不是一個開源的方案。
- 單一數據庫:
首先從配置一個網站應用開始,其由4太應用服務器及一個數據庫組成。下圖展示了一個應用的配置,數據庫配置max_connections為1000。為避免數據庫過載,我們將其並發請求數設置為800,因此設置每個應用服務器的連接池為允許最多200連接。設置每個應用服務器對於入站HTTP請求最少支持200線程的處理。
- 拆分數據庫:
現在假設我們采用拆分數據庫,其中有4個物理子庫(每個專用服務器上有1個單獨的MySQL實例)。現在我們有4個數據庫,每一個的 max_connections配置為1000。同樣,我們要限制每個數據庫800個並發事務。假設拆分架構的結果是在所有4個子庫上平均分布查詢,即每台應用服務器可以處理4倍的並發請求,並可以同每個子庫建立200個連接。
詳細的配置等可參考官方的文檔:
http://www.dbshards.cn/articles/database-sharding-configuration/
最后再說一句,這個是商用的不是免費的。
CUBRID
CUBRID 是一個全面開源,且完全免費的關系數據庫管理系統。CUBRID為高效執行Web應用進行了高度優化,特別是需要處理大數據量和高並發請求的復雜商務服務。通過提供獨特的最優化特性,CUBRID可以支持更多的並發請求,更少的響應時間。
CUBRID這個名稱,實際上是兩個單詞的組合:"Cube"(立方體)和"Bride"(橋梁)。對CUBRID而言,"Bride"代表"data bridge"(數據橋),而"Cube"代表密封盒子,可以為放在其中的數據提供安全。因此,CUBRID代表可以為機密信息提供安全保障。
從下表中可以對比一下cubrid的shards方案與其它的shards的不同之處:
大多數的解決方案都基於一個特定的數據庫。他們通常的方式是使用一個中間的代理層。也就是說每一次的SQL請求都需要經過解析。
cubrid的架構:
操作流程如下:
這是非常不錯的一個方案,可以考慮在團隊中推廣應用。
IBM WebSphere eXtreme Scale
IBM的分區方案,更確切的說應該是一套整體的方案:
1)WebSphere eXtreme Scale 初探,第 1 部分: 了解 WebSphere eXtreme Scale 及其工作原理
http://www.ibm.com/developerworks/cn/websphere/techjournal/0911_kirby/0911_kirby.html
2)Websphere eXtreme Scale 的先進先出(FIFO)特性研究
3)深入剖析 WebSphere eXtreme Scale HTTP 會話管理
http://www.ibm.com/developerworks/cn/websphere/techjournal/1301_ying/1301_ying.html
IBM® WebSphere® eXtreme Scale 是一種通用、高速的緩存解決方案,可在各種不同的設計中予以配置和使用。不過,您不能盲目地使用 WebSphere eXtreme Scale 提供的 API,並想當然地認為它會減輕數據庫的工作重負,使您的應用程序更快地運行。作為提高應用程序性能的一種策略,緩存應當被明智謹慎地應用。同樣地,您不能想當然地認為您的應用程序可以彈性地應對硬件故障,除非您為此籌備了有意識的計划。
最后還是要說一句,東西是好東西,可惜即不開源,也不免費。
MongoDB sharding
MongoDB 是一種流行的非關系型數據庫。作為一種文檔型數據庫,除了有無 schema 的靈活的數據結構,支持復雜、豐富的查詢功能外,MongoDB 還自帶了相當強大的 sharding 功能。
下面是架構圖:
關於更詳細的介紹,可以參考:
http://xiezhenye.com/2012/12/mongodb-sharding-%E6%9C%BA%E5%88%B6%E5%88%86%E6%9E%90.html
也可以參考官方的文檔:
http://docs.mongodb.org/manual/sharding/
這對於正在使用非關系型數據庫並且正用到分表功能的團隊可以說是一個福音。
MySQL Cluster
MySQL Cluster 是一種技術,該技術允許在無共享的系統中部署“內存中”數據庫的 Cluster 。通過無共享體系結構,系統能夠使用廉價的硬件,而且對軟硬件無特殊要求。此外,由於每個組件有自己的內存和磁盤,不存在單點故障。
MySQL Cluster 由一組計算機構成,每台計算機上均運行着多種進程,包括MySQL服務器,NDB Cluster 的數據節點,管理服務器,以及(可能)專門的數據訪問程序。關於 Cluster 中這些組件的關系。
如果想做mysql集群可以考慮使用。
Plugin for Grails
這個沒什么可說的,基於grails的shards插件。
網站是:
http://grails.org/plugin/sharding
Redis
redis-sharding 是一個由perl寫的 Redis 的proxy,使用它,你可以將數據分布存儲在多個Redis實例上,而在操作數據時卻像只操作一個實例一樣。利用它相當於透明地解決了 Redis 單線程無法有效利用多核心服務器的問題。當然,我們更期待官方的cluster方案。
項目地址:https://github.com/kni/redis-sharding
架構:
/- Redis (node 1) Client 1 --- /-- Redis (node 2) Redis Sharding --- Redis (node 3) Client 2 --- \-- Redis (node 4) \- Redis (node 5)
啟動redis-sharding,分別為使用默認host,port與指定host,port的方式:
perl redis_sharding.pl --nodes=10.1.1.2:6380,10.1.1.3:6380,... perl redis_sharding.pl --port=6379 --nodes=10.1.1.2:6380,10.1.1.3:6380,... perl redis_sharding.pl --host=10.1.1.1 --port=6379 --nodes=10.1.1.2:6380,10.1.1.3:6380,...
redis-sharding還支持重新切分數據,但這需要暫時停掉proxy,下面是將原來的db 9的數據重新sharding到B1-B5五個實例上:
停掉redis-sharding后再執行:
perl resharding.pl --db=9 --from=A1 --nodes=B1,B2,B3,B4,B5
perl resharding.pl --db=9 --from=A2 --nodes=B1,B2,B3,B4,B5
然后再啟動新的管理B1-B5的redis-sharding實例即可:
perl redis_sharding.pl --nodes=B1,B2,B3,B4,B5
如果需求簡單可以考慮使用。
Ruby ActiveRecord
功能和hibernate shards類似,都是基於orm的shard,如果使用ruby的朋友可以使用。
ScaleBase's Data Traffic Manager
ScaleBase 的關鍵賣點是它的旗艦產品 Data Traffic Manager。其最大的特點是可以跟客戶已有的應用協同工作,不需要客戶重寫應用。Data Traffic Manager 的作用相當於在數據庫與客戶端(可以是 app server、BI 工具或任何數據庫客戶端)之間充當代理,其部署方式可以是在本地或雲端。
商用產品,不多說,前景十分看好。
Solr Search Server
顧名思意:
solr提供的服務器分發。在處理搜索的可以深入一下。
SQLAlchemy ORM
SQLAlchemy是Python編程語言下的一款開源軟件。提供了SQL工具包及對象關系映射(ORM)工具,使用MIT許可證發行。
SQLAlchemy“采用簡單的Python語言,為高效和高性能的數據庫訪問設計,實現了完整的企業級持久模型”。SQLAlchemy的理念是,SQL數據庫的量級和性能重要於對象集合;而對象集合的抽象又重要於表和行。因此,SQLAlchmey采用了類似於Java里Hibernate的數據映射模型,而不是其他ORM框架采用的Active Record模型。不過,Elixir和declarative等可選插件可以讓用戶使用聲明語法。
如果你正在用python,而且想做分表的功能,可以重點關注下。
SQL Azure
microsoft的分片方案:
對於大數據分析高度可擴展的NoSQL數據庫是很熱門的話題,但是組織可以對傳統的關系型數據庫通過水平行分區進行橫向擴展和縱向擴展,使它們運行於多個服務器實例上,這也就是所謂的分片技術(Sharding)。 SQL Azure是定制版SQL Server 2008 R2集群基於雲的實現,運行於微軟公司全球數據中心網絡上。SQL Azure提供了高達99.9%服務級別協議的高可用性,由三重數據復制實現,省下了為處理運營高峰負載壓力需要在服務器硬件上的資本投資。
SQL Azure服務是在12月12日發布的,該版本把SQL Azure數據庫的最大容量從50GB增加到了150GB,引入了稱之為SQL Azure Federation的分片技術,隱性地降低了每月運營成本達到45%到95%之多,具體比例依賴於數據庫大小。Federations使重新分配和划分數據更容易了,而且提供了無需應用停機處理這些操作的路由層。
DBA和開發人員如何利用SQL Azure發揮他們的T-SQL管理技能,並能夠消除按需分配數據庫服務器的常規配置和維護成本呢?需要做聯邦的數據來源於接近800萬行的 Windows Azure表特征數據,這些數據來自於六個默認的計數器:網絡接口每秒發送的字節數和接收的字節數,每秒鍾ASP.NET應用請求數,建立的TCPv4連接數,內存可用字節和處理時間百分比。SQL Server 2008 R2 SP1源表(WADPerfCounters)有一個組合的集群主鍵,由PartitionKey和RowKey值組成。SQL Azure目標表做聯邦后增加了CounterID值,從1到6,代表了六個時間計數器。這些表給他們的主鍵增加了CounterID,因為必須包含聯邦分發主鍵值。
如果你正在跟微軟合作或者考慮使用微軟的方案,可以選用。
IBM Informix
IBM的數據庫:
IBM Informix 關系數據庫管理系統為所有規模的企業提供了聯機事務處理和決策支持應用,適用於Microsoft Windows、Linux、UNIX 和 Apple Mac OS X 平台。
如果使用這個數據庫可以使用它的shard功能。
Gizzard
Twitter已經從以往的數據存儲開發經驗中提出一個名為Gizzard的Scala框架,讓用戶可以更方便地創建自定義容錯、分布式數據庫。 Twitter給出了一個名為“Rowz”的示例,方便用戶上手。Twitter還公布了Gizzard的完整代碼。有了Gizzard,初創公司和小公司就可以更好更快地處理大量數據,從而利用更少的資源滿足用戶需求。
它更像是一個數據shards的方案之一,可以不使用關系型數據庫。
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 數據庫。
Amoeba
Amoeba是一個以MySQL為底層數據存儲,並對應用提供MySQL協議接口的proxy。它集中地響應應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上執行。基於此可以實現負載均衡、讀寫分離、高可用性等需求。與MySQL官方的MySQL Proxy相比,作者強調的是amoeba配置的方便(基於XML的配置文件,用SQLJEP語法書寫規則,比基於lua腳本的MySQL Proxy簡單)。
Amoeba相當於一個SQL請求的路由器,目的是為負載均衡、讀寫分離、高可用性提供機制,而不是完全實現它們。用戶需要結合使用MySQL的 Replication等機制來實現副本同步等功能。amoeba對底層數據庫連接管理和路由實現也采用了可插撥的機制,第三方可以開發更高級的策略類來替代作者的實現。這個程序總體上比較符合KISS原則的思想。
主要解決以下問題:
a). 數據切分后復雜數據源整合
b). 提供數據切分規則並降低數據切分規則給數據庫帶來的影響
c). 降低數據庫與客戶端連接
d). 讀寫分離路由
Amoeba For MySQL是專門針對MySQL數據庫的方案,架構示意圖:
Amoeba For Aiadin是個更通用的方案,他前端接收MySQL協議的請求,后端可以使用MySQL、Oracle、PostGreSql等其他數據源,這些對應用程序是透明的。架構示意圖:
altas
Atlas是由奇虎360公司Web平台部基礎架構組開發維護的一個基於MySQL協議的數據中間層項目。它在MySQL官方推出的MySQL- Proxy 0.8.2版本的基礎上,修改了大量bug,添加了很多功能特性。目前該項目在360公司內部得到了廣泛應用,3/4以上的MySQL業務已經接入了 Atlas平台,每天承載的讀寫請求數達20億條以上。
主要功能特性:
1. 自動讀寫分離,對應用透明
2. 自動分表
3. IP過濾,包括指定具體IP和網段IP
4. SQL語句黑白名單
5. 字符集和默認數據庫的自動修正
6. 可強制讀主庫,避免從庫的同步延遲
7. 主庫宕機的情況下讀操作不受影響
8. 在掛接LVS的情況下可平滑重啟,應用不感知
9. 自動檢測DB狀態,故障或連接不上的DB自動摘除,不再導入請求,在故障或網絡恢復后自動重新導入請求
10. 可在線手動將某台DB設置為上線或下線狀態
11. 可在線手動增加或減少一台DB
12. 從庫間加權的負載均衡
官方網址:
https://github.com/Qihoo360/Atlas
剛開源出來不久,文檔較少,不過可以嘗試使用,畢竟中國自己的開源框架嗎。
cobar
Cobar是關系型數據的分布式處理系統,它可以在分布式的環境下看上去像傳統數據庫一樣為您提供海量數據服務。
- 產品在阿里巴巴B2B公司已經穩定運行了3年以上。
- 目前已經接管了3000+個MySQL數據庫的schema,為應用提供數據服務。
- 據最近統計cobar集群目前平均每天處理近50億次的SQL執行請求。
不解釋,阿里團隊開源出來的產品。
詳細可到官方網址:
http://code.alibabatech.com/wiki/display/cobar/Home
最后
具體使用哪款產品還要根據實際的情況,及數據量等實際的需求。“只有合適才是最好的!”