天天看點

資料庫Sharding的基本思想和切分政策

一、基本思想

      sharding的基本思想就要把一個資料庫切分成多個部分放到不同的資料庫(server)上,進而緩解單一資料庫的性能問題。不太嚴格的講,對于海量資料的資料庫,如果是因為表多而資料多,這時候适合使用垂直切分,即把關系緊密(比如同一子產品)的表切分出來放在一個server上。如果表并不多,但每張表的資料非常多,這時候适合水準切分,即把表的資料按某種規則(比如按id散列)切分到多個資料庫(server)上。當然,現實中更多是這兩種情況混雜在一起,這時候需要根據實際情況做出選擇,也可能會綜合使用垂直與水準切分,進而将原有資料庫切分成類似矩陣一樣可以無限擴充的資料庫(server)陣列。下面分别詳細地介紹一下垂直切分和水準切分.

      垂直切分的最大特點就是規則簡單,實施也更為友善,尤其适合各業務之間的耦合度非

常低,互相影響很小,業務邏輯非常清晰的系統。在這種系統中,可以很容易做到将不同業

務子產品所使用的表分拆到不同的資料庫中。根據不同的表來進行拆分,對應用程式的影響也

更小,拆分規則也會比較簡單清晰。(這也就是所謂的”share nothing”)。

資料庫Sharding的基本思想和切分政策

      水準切分于垂直切分相比,相對來說稍微複雜一些。因為要将同一個表中的不同資料拆

分到不同的資料庫中,對于應用程式來說,拆分規則本身就較根據表名來拆分更為複雜,後

期的資料維護也會更為複雜一些。

資料庫Sharding的基本思想和切分政策

      讓我們從普遍的情況來考慮資料的切分:一方面,一個庫的所有表通常不可能由某一張表全部串聯起來,這句話暗含的意思是,水準切分幾乎都是針對一小搓一小搓(實際上就是垂直切分出來的塊)關系緊密的表進行的,而不可能是針對所有表進行的。另一方面,一些負載非常高的系統,即使僅僅隻是單個表都無法通過單台資料庫主機來承擔其負載,這意味着單單是垂直切分也不能完全解決問明。是以多數系統會将垂直切分和水準切分聯合使用,先對系統做垂直切分,再針對每一小搓表的情況選擇性地做水準切分。進而将整個資料庫切分成一個分布式矩陣。

資料庫Sharding的基本思想和切分政策

二、切分政策

      如前面所提到的,切分是按先垂直切分再水準切分的步驟進行的。垂直切分的結果正好為水準切分做好了鋪墊。垂直切分的思路就是分析表間的聚合關系,把關系緊密的表放在一起。多數情況下可能是同一個子產品,或者是同一“聚集”。這裡的“聚集”正是領域驅動設計裡所說的聚集。在垂直切分出的表聚集内,找出“根元素”(這裡的“根元素”就是領域驅動設計裡的“聚合根”),按“根元素”進行水準切分,也就是從“根元素”開始,把所有和它直接與間接關聯的資料放入一個shard裡。這樣出現跨shard關聯的可能性就非常的小。應用程式就不必打斷既有的表間關聯。比如:對于社交網站,幾乎所有資料最終都會關聯到某個使用者上,基于使用者進行切分就是最好的選擇。再比如論壇系統,使用者和論壇兩個子產品應該在垂直切分時被分在了兩個shard裡,對于論壇子產品來說,forum顯然是聚合根,是以按forum進行水準切分,把forum裡所有的文章和回帖都随forum放在一個shard裡是很自然的。

      對于共享資料資料,如果是隻讀的字典表,每個shard裡維護一份應該是一個不錯的選擇,這樣不必打斷關聯關系。如果是一般資料間的跨節點的關聯,就必須打斷。

      需要特别說明的是:當同時進行垂直和水準切分時,切分政策會發生一些微妙的變化。比如:在隻考慮垂直切分的時候,被劃分到一起的表之間可以保持任意的關聯關系,是以你可以按“功能子產品”劃分表格,但是一旦引入水準切分之後,表間關聯關系就會受到很大的制約,通常隻能允許一個主表(以該表id進行散列的表)和其多個次表之間保留關聯關系,也就是說:當同時進行垂直和水準切分時,在垂直方向上的切分将不再以“功能子產品”進行劃分,而是需要更加細粒度的垂直切分,而這個粒度與領域驅動設計中的“聚合”概念不謀而合,甚至可以說是完全一緻,每個shard的主表正是一個聚合中的聚合根!這樣切分下來你會發現資料庫分被切分地過于分散了(shard的數量會比較多,但是shard裡的表卻不多),為了避免管理過多的資料源,充分利用每一個資料庫伺服器的資源,可以考慮将業務上相近,并且具有相近資料增長速率(主表資料量在同一數量級上)的兩個或多個shard放到同一個資料源裡,每個shard依然是獨立的,它們有各自的主表,并使用各自主表id進行散列,不同的隻是它們的散列取模(即節點數量)必需是一緻的。(

1.事務問題:

解決事務問題目前有兩種可行的方案:分布式事務和通過應用程式與資料庫共同控制實作事務下面對兩套方案進行一個簡單的對比。

方案一:使用分布式事務

    優點:交由資料庫管理,簡單有效

    缺點:性能代價高,特别是shard越來越多時

方案二:由應用程式和資料庫共同控制

     原理:将一個跨多個資料庫的分布式事務分拆成多個僅處

           于單個資料庫上面的小事務,并通過應用程式來總控

           各個小事務。

     優點:性能上有優勢

     缺點:需要應用程式在事務控制上做靈活設計。如果使用   

           了spring的事務管理,改動起來會面臨一定的困難。

2.跨節點join的問題

      隻要是進行切分,跨節點join的問題是不可避免的。但是良好的設計和切分卻可以減少此類情況的發生。解決這一問題的普遍做法是分兩次查詢實作。在第一次查詢的結果集中找出關聯資料的id,根據這些id發起第二次請求得到關聯資料。

3.跨節點的count,order by,group by以及聚合函數問題

      這些是一類問題,因為它們都需要基于全部資料集合進行計算。多數的代理都不會自動處理合并工作。解決方案:與解決跨節點join問題的類似,分别在各個節點上得到結果後在應用程式端進行合并。和join不同的是每個結點的查詢可以并行執行,是以很多時候它的速度要比單一大表快很多。但如果結果集很大,對應用程式記憶體的消耗是一個問題。

參考資料:

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

轉自:http://blog.csdn.net/bluishglc/article/details/6161475/

特别說明:尊重作者的勞動成果,轉載請注明出處哦~~~http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt331