1. 程式人生 > >資料庫切分(3)之資料庫切分實施策略和示例演示

資料庫切分(3)之資料庫切分實施策略和示例演示


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.實施階段