數據庫分庫分表(sharding)系列(一) 拆分實施策略和示例演示

[置頂] 數據庫分庫分表(sharding)系列(一) 拆分實施策略和示例演示

  11192人閱讀  評論(1)  收藏  舉報

本文原文鏈接: http://blog.csdn.net/bluishglc/article/details/7696085 ,轉載請註明出處!本文着重介紹sharding切分策略,若是你對數據庫sharding缺乏基本的瞭解,請參考我另外一篇從基礎理論全面介紹sharding的文章:數據庫Sharding的基本思想和切分策略html

 

第一部分:實施策略java

 

 

圖1.數據庫分庫分表(sharding)實施策略圖解(點擊查看大圖)sql


1.準備階段

對數據庫進行分庫分表(Sharding化)前,須要開發人員充分了解系統業務邏輯和數據庫schema.一個好的建議是繪製一張數據庫ER圖或領域模型圖,以這類圖爲基礎劃分shard,直觀易行,能夠確保開發人員始終保持清醒思路。對因而選擇數據庫ER圖仍是領域模型圖要根據項目自身狀況進行選擇。若是項目使用數據驅動的開發方式,團隊以數據庫ER圖做爲業務交流的基礎,則天然會選擇數據庫ER圖,若是項目使用的是領域驅動的開發方式,並經過OR-Mapping構建了一個良好的領域模型,那麼領域模型圖無疑是最好的選擇。就我我的來講,更加傾向使用領域模型圖,由於進行切分時更多的是以業務爲依據進行分析判斷,領域模型無疑更加清晰和直觀。

2.分析階段

1. 垂直切分

垂直切分的依據原則是:將業務緊密,表間關聯密切的表劃分在一塊兒,例如同一模塊的表。結合已經準備好的數據庫ER圖或領域模型圖,仿照活動圖中的泳道概念,一個泳道表明一個shard,把全部表格劃分到不一樣的泳道中。下面的分析示例會展現這種作法。固然,你也能夠在打印出的ER圖或模型圖上直接用鉛筆圈,一切取決於你本身的喜愛。

2. 水平切分
垂直切分後,須要對shard內表格的數據量和增速進一步分析,以肯定是否須要進行水平切分。

2.1若劃分到一塊兒的表格數據增加緩慢,在產品上線後可碰見的足夠長的時期內都可以由單一數據庫承載,則不須要進行水平切分,全部表格駐留同一shard,全部表間關聯關係會獲得最大限度的保留,同時保證了書寫SQL的自由度,不易受join、group by、order by等子句限制。

2.2 若劃分到一塊兒的表格數據量巨大,增速迅猛,須要進一步進行水平分割。進一步的水平分割就這樣進行:

2.2.1.結合業務邏輯和表間關係,將當前shard劃分紅多個更小的shard,一般狀況下,這些更小的shard每個都只包含一個主表(將以該表ID進行散列的表)和多個與其關聯或間接關聯的次表。這種一個shard一張主表多張次表的情況是水平切分的必然結果。這樣切分下來,shard數量就會迅速增多。若是每個shard表明一個獨立的數據庫,那麼管理和維護數據庫將會很是麻煩,並且這些小shard每每只有兩三張表,爲此而創建一個新庫,利用率並不高,所以,在水平切分完成後可再進行一次「反向的Merge」,即:將業務上相近,而且具備相近數據增加速率(主表數據量在同一數量級上)的兩個或多個shard放到同一個數據庫上,在邏輯上它們依然是獨立的shard,有各自的主表,並依據各自主表的ID進行散列,不一樣的只是它們的散列取模(即節點數量)必需是一致的。這樣,每一個數據庫結點上的表格數量就相對平均了。

2.2.2. 全部表格均劃分到合適的shard以後,全部跨越shard的表間關聯都必須打斷,在書寫sql時,跨shard的join、group by、order by都將被禁止,須要在應用程序層面協調解決這些問題。

特別想提一點:經水平切分後,shard的粒度每每要比只作垂直切割的粒度要小,原單一垂直shard會被細分爲一到多個以一個主表爲中心關聯或間接關聯多個次表的shard,此時的shard粒度與領域驅動設計中的「聚合」概念不謀而合,甚至能夠說是徹底一致,每一個shard的主表正是一個聚合中的聚合根!

3.實施階段數據庫


若是項目在開發伊始就決定進行分庫分表,則嚴格按照分析設計方案推動便可。若是是在中期架構演進中實施,除搭建實現sharding邏輯的基礎設施外(關於該話題會在下篇文章中進行闡述),還須要對原有SQL逐一過濾分析,修改那些由於sharding而受到影響的sql.

第二部分:示例演示

本文選擇一我的盡皆知的應用:jpetstore來演示如何進行分庫分表(sharding)在分析階段的工做。因爲一些我的緣由,演示使用的jpetstore來自原ibatis官方的一個Demo版本,SVN地址爲:http://mybatis.googlecode.com/svn/tags/java_release_2.3.4-726/jpetstore-5。關於jpetstore的業務邏輯這裏再也不介紹,這是一個很是簡單的電商系統原型,其領域模型以下圖:mybatis

 

圖2. jpetstore領域模型架構

 

因爲系統較簡單,咱們很容易從模型上看出,其主要由三個模塊組成:用戶,產品和訂單。那麼垂直切分的方案也就出來了。接下來看水平切分,若是咱們從一個實際的寵物店出發考慮,可能出現數據激增的單表應該是Account和Order,所以這兩張表須要進行水平切分。對於Product模塊來講,若是是一個實際的系統,Product和Item的數量都不會很大,所以只作垂直切分就足夠了,也就是(Product,Category,Item,Iventory,Supplier)五張表在一個數據庫結點上(沒有水平切分,不會存在兩個以上的數據庫結點)。可是做爲一個演示,咱們假設產品模塊也有大量的數據須要咱們作水平切分,那麼分析來看,這個模塊要拆分出兩個shard:一個是(Product(主),Category),另外一個是(Item(主),Iventory,Supplier),同時,咱們認爲:這兩個shard在數據增速上應該是相近的,且在業務上也很緊密,那麼咱們能夠把這兩個shard放在同一個數據庫節點上,Item和Product數據在散列時取同樣的模。根據前文介紹的圖紙繪製方法,咱們獲得下面這張sharding示意圖:app

 

圖3. jpetstore sharding示意圖svn

 

對於這張圖再說明幾點:post


1.使用泳道表示物理shard(一個數據庫結點)ui

2.若垂直切分出的shard進行了進一步的水平切分,但公用一個物理shard的話,則用虛線框住,表示其在邏輯上是一個獨立的shard。

3.深色實體表示主表

4.X表示須要打斷的表間關聯

相關文章
相關標籤/搜索