您好,登錄后才能下訂單哦!
DB分庫分表的基本思想和切分策略是怎樣的,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
一、基本思想
Sharding的基本思想就要把一個數(shù)據(jù)庫切分成多個部分放到不同的數(shù)據(jù)庫(server)上,從而緩解單一數(shù)據(jù)庫的性能問題。不太嚴格的講,對于海量數(shù)據(jù)的數(shù)據(jù)庫,如果是因為表多而數(shù)據(jù)多,這時候適合使用垂直切分,即把關(guān)系緊密(比如同一模塊)的表切分出來放在一個server上。如果表并不多,但每張表的數(shù)據(jù)非常多,這時候適合水平切分,即把表的數(shù)據(jù)按某種規(guī)則(比如按ID散列)切分到多個數(shù)據(jù)庫(server)上。當然,現(xiàn)實中更多是這兩種情況混雜在一起,這時候需要根據(jù)實際情況做出選擇,也可能會綜合使用垂直與水平切分,從而將原有數(shù)據(jù)庫切分成類似矩陣一樣可以***擴充的數(shù)據(jù)庫(server)陣列。下面分別詳細地介紹一下垂直切分和水平切分.
垂直切分的***特點就是規(guī)則簡單,實施也更為方便,尤其適合各業(yè)務(wù)之間的耦合度非常低,相互影響很小,業(yè)務(wù)邏輯非常清晰的系統(tǒng)。在這種系統(tǒng)中,可以很容易做到將不同業(yè)務(wù)模塊所使用的表分拆到不同的數(shù)據(jù)庫中。根據(jù)不同的表來進行拆分,對應(yīng)用程序的影響也更小,拆分規(guī)則也會比較簡單清晰。(這也就是所謂的”share nothing”)。
水平切分于垂直切分相比,相對來說稍微復(fù)雜一些。因為要將同一個表中的不同數(shù)據(jù)拆分到不同的數(shù)據(jù)庫中,對于應(yīng)用程序來說,拆分規(guī)則本身就較根據(jù)表名來拆分更為復(fù)雜,后期的數(shù)據(jù)維護也會更為復(fù)雜一些。
讓我們從普遍的情況來考慮數(shù)據(jù)的切分:一方面,一個庫的所有表通常不可能由某一張表全部串聯(lián)起來,這句話暗含的意思是,水平切分幾乎都是針對一小搓一小搓(實際上就是垂直切分出來的塊)關(guān)系緊密的表進行的,而不可能是針對所有表進行的。另一方面,一些負載非常高的系統(tǒng),即使僅僅只是單個表都無法通過單臺數(shù)據(jù)庫主機來承擔其負載,這意味著單單是垂直切分也不能完全解決問明。因此多數(shù)系統(tǒng)會將垂直切分和水平切分聯(lián)合使用,先對系統(tǒng)做垂直切分,再針對每一小搓表的情況選擇性地做水平切分。從而將整個數(shù)據(jù)庫切分成一個分布式矩陣。
二、切分策略
如前面所提到的,切分是按先垂直切分再水平切分的步驟進行的。垂直切分的結(jié)果正好為水平切分做好了鋪墊。垂直切分的思路就是分析表間的聚合關(guān)系,把關(guān)系緊密的表放在一起。多數(shù)情況下可能是同一個模塊,或者是同一“聚集”。這里的“聚集”正是領(lǐng)域驅(qū)動設(shè)計里所說的聚集。在垂直切分出的表聚集內(nèi),找出“根元素”(這里的“根元素”就是領(lǐng)域驅(qū)動設(shè)計里的“聚合根”),按“根元素”進行水平切分,也就是從“根元素”開始,把所有和它直接與間接關(guān)聯(lián)的數(shù)據(jù)放入一個shard里。這樣出現(xiàn)跨shard關(guān)聯(lián)的可能性就非常的小。應(yīng)用程序就不必打斷既有的表間關(guān)聯(lián)。比如:對于社交網(wǎng)站,幾乎所有數(shù)據(jù)最終都會關(guān)聯(lián)到某個用戶上,基于用戶進行切分就是***的選擇。再比如論壇系統(tǒng),用戶和論壇兩個模塊應(yīng)該在垂直切分時被分在了兩個shard里,對于論壇模塊來說,F(xiàn)orum顯然是聚合根,因此按Forum進行水平切分,把Forum里所有的帖子和回帖都隨Forum放在一個shard里是很自然的。
對于共享數(shù)據(jù)數(shù)據(jù),如果是只讀的字典表,每個shard里維護一份應(yīng)該是一個不錯的選擇,這樣不必打斷關(guān)聯(lián)關(guān)系。如果是一般數(shù)據(jù)間的跨節(jié)點的關(guān)聯(lián),就必須打斷。
需要特別說明的是:當同時進行垂直和水平切分時,切分策略會發(fā)生一些微妙的變化。比如:在只考慮垂直切分的時候,被劃分到一起的表之間可以保持任意的關(guān)聯(lián)關(guān)系,因此你可以按“功能模塊”劃分表格,但是一旦引入水平切分之后,表間關(guān)聯(lián)關(guān)系就會受到很大的制約,通常只能允許一個主表(以該表ID進行散列的表)和其多個次表之間保留關(guān)聯(lián)關(guān)系,也就是說:當同時進行垂直和水平切分時,在垂直方向上的切分將不再以“功能模塊”進行劃分,而是需要更加細粒度的垂直切分,而這個粒度與領(lǐng)域驅(qū)動設(shè)計中的“聚合”概念不謀而合,甚至可以說是完全一致,每個shard的主表正是一個聚合中的聚合根!這樣切分下來你會發(fā)現(xiàn)數(shù)據(jù)庫分被切分地過于分散了(shard的數(shù)量會比較多,但是shard里的表卻不多),為了避免管理過多的數(shù)據(jù)源,充分利用每一個數(shù)據(jù)庫服務(wù)器的資源,可以考慮將業(yè)務(wù)上相近,并且具有相近數(shù)據(jù)增長速率(主表數(shù)據(jù)量在同一數(shù)量級上)的兩個或多個shard放到同一個數(shù)據(jù)源里,每個shard依然是獨立的,它們有各自的主表,并使用各自主表ID進行散列,不同的只是它們的散列取模(即節(jié)點數(shù)量)必需是一致的。
1.事務(wù)問題
解決事務(wù)問題目前有兩種可行的方案:分布式事務(wù)和通過應(yīng)用程序與數(shù)據(jù)庫共同控制實現(xiàn)事務(wù)下面對兩套方案進行一個簡單的對比。
方案一:使用分布式事務(wù)
優(yōu)點:交由數(shù)據(jù)庫管理,簡單有效
缺點:性能代價高,特別是shard越來越多時
方案二:由應(yīng)用程序和數(shù)據(jù)庫共同控制
原理:將一個跨多個數(shù)據(jù)庫的分布式事務(wù)分拆成多個僅處于單個數(shù)據(jù)庫上面的小事務(wù),并通過應(yīng)用程序來總控各個小事務(wù)。
優(yōu)點:性能上有優(yōu)勢
缺點:需要應(yīng)用程序在事務(wù)控制上做靈活設(shè)計。如果使用了spring的事務(wù)管理,改動起來會面臨一定的困難。
2.跨節(jié)點Join的問題
只要是進行切分,跨節(jié)點Join的問題是不可避免的。但是良好的設(shè)計和切分卻可以減少此類情況的發(fā)生。解決這一問題的普遍做法是分兩次查詢實現(xiàn)。在***次查詢的結(jié)果集中找出關(guān)聯(lián)數(shù)據(jù)的id,根據(jù)這些id發(fā)起第二次請求得到關(guān)聯(lián)數(shù)據(jù)。
3.跨節(jié)點的count,order by,group by以及聚合函數(shù)問題
這些是一類問題,因為它們都需要基于全部數(shù)據(jù)集合進行計算。多數(shù)的代理都不會自動處理合并工作。解決方案:與解決跨節(jié)點join問題的類似,分別在各個節(jié)點上得到結(jié)果后在應(yīng)用程序端進行合并。和join不同的是每個結(jié)點的查詢可以并行執(zhí)行,因此很多時候它的速度要比單一大表快很多。但如果結(jié)果集很大,對應(yīng)用程序內(nèi)存的消耗是一個問題。
關(guān)于垂直切分Vertical Sharding的粒度
垂直切分的粒度指的是在做垂直切分時允許幾級的關(guān)聯(lián)表放在一個shard里.這個問題對應(yīng)用程序和sharding實現(xiàn)有著很大的影響.
關(guān)聯(lián)打斷地越多,則受影響的join操作越多,應(yīng)用程序為此做出的妥協(xié)就越大,但單表的路由會越簡單,與業(yè)務(wù)的關(guān)聯(lián)性會越小,就越容易使用統(tǒng)一機制處理.在此方向上的極端方案是:打斷所有連接,每張表都配有路由規(guī)則,可以使用統(tǒng)一機制或框架自動處理.比如amoeba這樣的框架,它的路由能且僅能通過SQL的特征(比如某個表的id)進行路由.
反之,若關(guān)聯(lián)打斷地越少,則join操作的受到的限制就小,應(yīng)用程序需要做出的妥協(xié)就越小,但是表的路由就會變復(fù)雜,與業(yè)務(wù)的關(guān)聯(lián)性就越大,就越難使用統(tǒng)一機制處理,需要針對每個數(shù)據(jù)請求單獨實現(xiàn)路由.在此方向上的極端方案是:所有表都在一個shard里,也就是沒有垂直切分,這樣就沒有關(guān)聯(lián)被打斷.當然這是非常極端的,除非整個數(shù)據(jù)庫很簡單,表的數(shù)量很少.
實際的粒度掌控需要結(jié)合“業(yè)務(wù)緊密程度”和“表格數(shù)據(jù)量”兩個因素綜合考慮,一般來說:
若劃歸到一起的表格關(guān)系緊密,且數(shù)據(jù)量并不大,增速也非常緩慢,則適宜放在一個shard里,不需要再進行水平切分;
若劃歸到一起的表格數(shù)據(jù)量巨大且增速迅猛,則勢必要在垂直切分的基礎(chǔ)上再進行水平切分,水平切分就意味著原單一shard會被細分成多個更小的shard,每一個shard存在一個主表(即會以該表ID進行散列的表)和多個相之相關(guān)的關(guān)聯(lián)表。
總之,垂直切分的粒度在兩個相反的方向上呈現(xiàn)優(yōu)勢與劣勢并存并相互博弈的局面.架構(gòu)師需要做的是結(jié)合項目的實際情況在兩者之間取得收益化的平衡.
看完上述內(nèi)容,你們掌握DB分庫分表的基本思想和切分策略是怎樣的的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。