數據庫Sharding的基本思想和切分策略

本文着重介紹sharding的基本思想和理論上的切分策略,關於更加細緻的實施策略和參考事例請參考個人另外一篇博文:數據庫分庫分表(sharding)系列(一) 拆分實施策略和示例演示 spring

 

1、基本思想數據庫

      Sharding的基本思想就要把一個數據庫切分紅多個部分放到不一樣的數據庫(server)上,從而緩解單一數據庫的性能問題。不太嚴格的講,對於海量數據的數據庫,若是是由於表多而數據多,這時候適合使用垂直切分,即把關係緊密(好比同一模塊)的表切分出來放在一個server上。若是表並很少,但每張表的數據很是多,這時候適合水平切分,即把表的數據按某種規則(好比按ID散列)切分到多個數據庫(server)上。固然,現實中更可能是這兩種狀況混雜在一塊兒,這時候須要根據實際狀況作出選擇,也可能會綜合使用垂直與水平切分,從而將原有數據庫切分紅相似矩陣同樣能夠無限擴充的數據庫(server)陣列。下面分別詳細地介紹一下垂直切分和水平切分.

      垂直切分的最大特色就是規則簡單,實施也更爲方便,尤爲適合各業務之間的耦合度非
常低,相互影響很小,業務邏輯很是清晰的系統。在這種系統中,能夠很容易作到將不一樣業
務模塊所使用的表分拆到不一樣的數據庫中。根據不一樣的表來進行拆分,對應用程序的影響也
更小,拆分規則也會比較簡單清晰。(這也就是所謂的」share nothing」)。服務器



      水平切分於垂直切分相比,相對來講稍微複雜一些。由於要將同一個表中的不一樣數據拆
分到不一樣的數據庫中,對於應用程序來講,拆分規則自己就較根據表名來拆分更爲複雜,後
期的數據維護也會更爲複雜一些。架構



      讓咱們從廣泛的狀況來考慮數據的切分:一方面,一個庫的全部表一般不可能由某一張表所有串聯起來,這句話暗含的意思是,水平切分幾乎都是針對一小搓一小搓(實際上就是垂直切分出來的塊)關係緊密的表進行的,而不多是針對全部表進行的。另外一方面,一些負載很是高的系統,即便僅僅只是單個表都沒法經過單臺數據庫主機來承擔其負載,這意味着單單是垂直切分也不能徹底解決問明。所以多數系統會將垂直切分和水平切分聯合使用,先對系統作垂直切分,再針對每一小搓表的狀況選擇性地作水平切分。從而將整個數據庫切分紅一個分佈式矩陣。框架

 

2、切分策略分佈式

      如前面所提到的,切分是按先垂直切分再水平切分的步驟進行的。垂直切分的結果正好爲水平切分作好了鋪墊。垂直切分的思路就是分析表間的聚合關係,把關係緊密的表放在一塊兒。多數狀況下多是同一個模塊,或者是同一「彙集」。這裏的「彙集」正是領域驅動設計裏所說的彙集。在垂直切分出的表彙集內,找出「根元素」(這裏的「根元素」就是領域驅動設計裏的「聚合根」),按「根元素」進行水平切分,也就是從「根元素」開始,把全部和它直接與間接關聯的數據放入一個shard裏。這樣出現跨shard關聯的可能性就很是的小。應用程序就沒必要打斷既有的表間關聯。好比:對於社交網站,幾乎全部數據最終都會關聯到某個用戶上,基於用戶進行切分就是最好的選擇。再好比論壇系統,用戶和論壇兩個模塊應該在垂直切分時被分在了兩個shard裏,對於論壇模塊來講,Forum顯然是聚合根,所以按Forum進行水平切分,把Forum裏全部的帖子和回帖都隨Forum放在一個shard裏是很天然的。

      對於共享數據數據,若是是隻讀的字典表,每一個shard裏維護一份應該是一個不錯的選擇,這樣沒必要打斷關聯關係。若是是通常數據間的跨節點的關聯,就必須打斷。函數

 

      須要特別說明的是:當同時進行垂直和水平切分時,切分策略會發生一些微妙的變化。好比:在只考慮垂直切分的時候,被劃分到一塊兒的表之間能夠保持任意的關聯關係,所以你能夠按「功能模塊」劃分表格,可是一旦引入水平切分以後,表間關聯關係就會受到很大的制約,一般只能容許一個主表(以該表ID進行散列的表)和其多個次表之間保留關聯關係,也就是說:當同時進行垂直和水平切分時,在垂直方向上的切分將再也不以「功能模塊」進行劃分,而是須要更加細粒度的垂直切分,而這個粒度與領域驅動設計中的「聚合」概念不謀而合,甚至能夠說是徹底一致,每一個shard的主表正是一個聚合中的聚合根!這樣切分下來你會發現數據庫分被切分地過於分散了(shard的數量會比較多,可是shard裏的表卻很少),爲了不管理過多的數據源,充分利用每個數據庫服務器的資源,能夠考慮將業務上相近,而且具備相近數據增加速率(主表數據量在同一數量級上)的兩個或多個shard放到同一個數據源裏,每一個shard依然是獨立的,它們有各自的主表,並使用各自主表ID進行散列,不一樣的只是它們的散列取模(即節點數量)必需是一致的。(性能

本文着重介紹sharding的基本思想和理論上的切分策略,關於更加細緻的實施策略和參考事例請參考個人另外一篇博文:數據庫分庫分表(sharding)系列(一) 拆分實施策略和示例演示 網站

ui


1.事務問題:
解決事務問題目前有兩種可行的方案:分佈式事務和經過應用程序與數據庫共同控制實現事務下面對兩套方案進行一個簡單的對比。
方案一:使用分佈式事務
    優勢:交由數據庫管理,簡單有效
    缺點:性能代價高,特別是shard愈來愈多時
方案二:由應用程序和數據庫共同控制
     原理:將一個跨多個數據庫的分佈式事務分拆成多個僅處
           於單個數據庫上面的小事務,並經過應用程序來總控
           各個小事務。
     優勢:性能上有優點
     缺點:須要應用程序在事務控制上作靈活設計。若是使用   
           了spring的事務管理,改動起來會面臨必定的困難。
2.跨節點Join的問題
      只要是進行切分,跨節點Join的問題是不可避免的。可是良好的設計和切分卻能夠減小此類狀況的發生。解決這一問題的廣泛作法是分兩次查詢實現。在第一次查詢的結果集中找出關聯數據的id,根據這些id發起第二次請求獲得關聯數據。

3.跨節點的count,order by,group by以及聚合函數問題
      這些是一類問題,由於它們都須要基於所有數據集合進行計算。多數的代理都不會自動處理合並工做。解決方案:與解決跨節點join問題的相似,分別在各個節點上獲得結果後在應用程序端進行合併。和join不一樣的是每一個結點的查詢能夠並行執行,所以不少時候它的速度要比單一大表快不少。但若是結果集很大,對應用程序內存的消耗是一個問題。

 

參考資料:

《MySQL性能調優與架構設計》

 

注:本文圖片摘自《MySQL性能調優與架構設計》一 書

 

 

 

相關閱讀:

數據庫分庫分表(sharding)系列(五) 一種支持自由規劃無須數據遷移和修改路由代碼的Sharding擴容方案

 

 

 

數據庫分庫分表(sharding)系列(四) 多數據源的事務處理

數據庫分庫分表(sharding)系列(三) 關於使用框架仍是自主開發以及sharding實現層面的考量

 

數據庫分庫分表(sharding)系列(二) 全局主鍵生成策略

 

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

 

關於垂直切分Vertical Sharding的粒度

數據庫Sharding的基本思想和切分策略

相關文章
相關標籤/搜索