第一部分:實施策略
數據庫分庫分表(sharding)實施策略圖解
1. 垂直切分
垂直切分的依據原則是:將業務緊密,表間關聯密切的表划分在一起,例如同一模塊的表。結合已經准備好的數據庫ER圖或領域模型圖,仿照活動圖中的泳道概念,一個泳道代表一個shard,把所有表格划分到不同的泳道中。
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都將被禁止,需要在應用程序層面協調解決這些問題。
第二部分:示例演示
這是一個非常簡單的電商系統原型,其領域模型如下圖:
由於系統較簡單,我們很容易從模型上看出,其主要由三個模塊組成:用戶,產品和訂單。那么垂直切分的方案也就出來了。接下來看水平切分,如果我們從一個實際的寵物店出發考慮,可能出現數據激增的單表應該是Account和Order,因此這兩張表需要進行水平切分。對於Product模塊來說,如果是一個實際的系統,Product和Item的數量都不會很大,因此只做垂直切分就足夠了,也就是(Product,Category,Item,Iventory,Supplier)五張表在一個數據庫結點上(沒有水平切分,不會存在兩個以上的數據庫結點)。但是作為一個演示,我們假設產品模塊也有大量的數據需要我們做水平切分,那么分析來看,這個模塊要拆分出兩個shard:一個是(Product(主),Category),另一個是(Item(主),Iventory,Supplier),同時,我們認為:這兩個shard在數據增速上應該是相近的,且在業務上也很緊密,那么我們可以把這兩個shard放在同一個數據庫節點上,Item和Product數據在散列時取一樣的模。根據前文介紹的圖紙繪制方法,我們得到下面這張sharding示意圖:
對於這張圖再說明幾點:
1.使用泳道表示物理shard(一個數據庫結點)
2.若垂直切分出的shard進行了進一步的水平切分,但公用一個物理shard的話,則用虛線框住,表示其在邏輯上是一個獨立的shard。
3.深色實體表示主表
4.X表示需要打斷的表間關聯