Sharding - 分庫分表

Sharding

隨著業(yè)務發(fā)展挪钓、用戶量的增長是越,技術團隊都會遇到數據量大、查詢緩慢碌上、大數據量的存儲問題倚评。一般來說,Mysql單庫超過5000萬條記錄馏予,Oracle單庫超過1億條記錄天梧,DB壓力就很大,當然容量大小和具體業(yè)務霞丧、字段數量呢岗、訪問模式、數據內容等都有進一步關系蛹尝。如果僅僅是查詢緩慢后豫,可以先從sql優(yōu)化、緩存突那、讀寫分離等手段解決挫酿。當數據量增長超過單庫限制時,很容易出現(xiàn)性能問題愕难,會自然而想到分庫分表存儲數據早龟,即sharding惫霸。

sharding分類

sharding指的是數據分片存儲,和數據庫的主備葱弟、讀寫分離不是一個問題壹店。主備是為了提高系統(tǒng)的高可用性;讀寫分離是應對某些情況下芝加,讀性能的優(yōu)化和要求茫打。sharding的基本思想就要把一個數據庫切分成多個部分放到不同的數據庫上,從而緩解單一數據庫的性能問題妖混。sharding可以大概分成兩類,垂直切分和水平切分轮洋。

  1. 垂直切分制市。對于海量數據的數據庫,如果是因為表多而數據多弊予,而每張表的數據量相差不大祥楣,這時候適合使用垂直切分,即把關系緊密(比如同一模塊)的一些表切分出來放在一個庫汉柒,從而將原來的單庫切分成多個庫误褪。
  2. 水平切分。對于表不多碾褂、但每張表的數據非常多的情形兽间,適合水平切分,即把表的數據按某種規(guī)則(比如按ID散列)切分到多個庫上正塌。
  3. 通常情況下嘀略,需要同時考慮水平切分和垂直切分,甚至也可以單庫內部做表拆分乓诽,實際的切分原則都需要考慮自己的實際情況帜羊。當同時進行垂直和水平切分時,切分策略會發(fā)生一些微妙的變化鸠天。比如:在只考慮垂直切分的時候讼育,被劃分到一起的表之間可以保持任意的關聯(lián)關系,因此你可以按“功能模塊”劃分表格稠集,但是一旦引入水平切分之后奶段,表間關聯(lián)關系就會受到很大的制約,通常只能允許一個主表(以該表ID進行散列的表)和其多個次表之間保留關聯(lián)關系巍杈,也就是說:當同時進行垂直和水平切分時忧饭,在垂直方向上的切分將不再以“功能模塊”進行劃分,而是需要更加細粒度的垂直切分筷畦,而這個粒度與領域驅動設計中的“聚合”概念不謀而合词裤,甚至可以說是完全一致刺洒,每個shard的主表正是一個聚合中的聚合根!這樣切分下來你會發(fā)現(xiàn)數據庫分被切分地過于分散了(shard的數量會比較多吼砂,但是shard里的表卻不多)逆航,為了避免管理過多的數據源,充分利用每一個數據庫服務器的資源渔肩,可以考慮將業(yè)務上相近因俐,并且具有相近數據增長速率(主表數據量在同一數量級上)的兩個或多個shard放到同一個數據源里,每個shard依然是獨立的周偎,它們有各自的主表抹剩,并使用各自主表ID進行散列,不同的只是它們的散列取模(即節(jié)點數量)必需是一致的.

sharding中需要解決的問題

  1. 事務問題蓉坎。當同一個業(yè)務中涉及到多庫時澳眷,就需要考慮分布式事務了。對于分布式事務的解決蛉艾,有多種方案钳踊,比如兩階段提交、一階段提交勿侯、Best Efforts 1PC模式和事務補償機制等拓瞪。
  2. 數據遷移,容量規(guī)劃助琐,擴容等問題祭埂。建議利用對2的倍數取余具有向前兼容的特性(如對4取余得1的數對2取余也是1)來分配數據,避免了行級別的數據遷移弓柱,但是依然需要進行表級別的遷移沟堡,同時對擴容規(guī)模和分表數量都有限制。
  3. 跨節(jié)點sql矢空。如跨節(jié)點join航罗、count、order by屁药、group by以及聚合函數等粥血。只要是進行切分,跨節(jié)點Join的問題是不可避免的酿箭。但是良好的設計和切分卻可以減少此類情況的發(fā)生复亏。解決這一問題的普遍做法是分兩次查詢實現(xiàn)。在第一次查詢的結果集中找出關聯(lián)數據的id,根據這些id發(fā)起第二次請求得到關聯(lián)數據缭嫡。因為它們都需要基于全部數據集合進行計算缔御。count、group by等問題妇蛀,一般的解決方案是分別在各個節(jié)點上得到結果后在應用程序端進行合并耕突。和join不同的是每個結點的查詢可以并行執(zhí)行笤成,因此很多時候它的速度要比單一大表快很多。但如果結果集很大眷茁,對應用程序內存的消耗是一個問題炕泳。
  4. 分布式唯一ID問題。BIGINT型可以使用Twitter的分布式自增ID算法Snowflake上祈,VARCHAR類型可以考慮UUID培遵。但是Snowflake也會有自己的問題,比如某些場景登刺,生成的值大部分都是偶數籽腕。
  5. sharding的時候還需要考慮自身的業(yè)務。比如根據用戶ID分訂單表纸俭,有些用戶根本不下單节仿,但是可能有些用戶的訂單量占比超過總量的80%,如果這些用戶被sharding在了同一個庫和表中掉蔬,實際的sharding效果就會很差。這種情況就需要自定義分表規(guī)則矾瘾。

中間件

對于Java服務來講女轿,很大的一個優(yōu)勢就是生態(tài)完善,組件齊全壕翩。sharding也是如此蛉迹。sharding的中間件大概可以分成兩大類,一種是基于jdbc的lib組件放妈,一種是基于代理(Proxy)的中間件北救。基于jdbc的lib組件芜抒,好處在于易于和Java服務集成珍策、輕量;易于上手宅倒,無運維成本攘宙;業(yè)務直接到數據庫,少一層proxy理論上性能更好拐迁〔渑基于Proxy的中間件,需要在所有的數據源中間搭一個Proxy服務线召,Java的數據源只連接到Proxy上铺韧,由Proxy負責底層的分庫分表,以及請求路由缓淹,優(yōu)勢在于解耦性比較高哈打;可以找專門的DBA負責和運維Proxy塔逃,分庫分表操作對于Java程序員透明化;易于實現(xiàn)監(jiān)控前酿、數據遷移患雏、連接管理等功能;劣勢就是運維成本的增加罢维,小公司可能沒有預算請專門的DBA和運維人員來做這個解耦工作淹仑。

lib組件包括:當當網sharding-sphere、蘑菇街TSharding肺孵;
基于Proxy的中間件:TDDL匀借、DBProxy、Atlas平窘、oneproxy吓肋、vitess、mycat瑰艘、cobar等是鬼。此處就不做各個中間件的對比了。

代碼

https://github.com/chxfantasy/dynamic-datasource-with-sharding-starter

這里實現(xiàn)了一個支持多庫路由紫新、分庫分表的spring-boot-starter均蜜,基于baomidou/dynamic-datasource-spring-boot-startersharding-sphere

dynamic-datasource本身是為了在同一個系統(tǒng)中支持多庫,包括主備芒率、讀寫分離囤耳、多庫等,多個讀庫時偶芍,支持定義負載均衡算法充择;sharding-sphere是基于lib的分庫分表組件,可以根據配置的規(guī)則動態(tài)路由到相關庫和表匪蟀。在我的代碼中椎麦,sharding-sphere做一個dynamic-datasource的一個數據源。

一個問題:既然sharding-shpere本身已經支持多庫材彪、分庫和分表铃剔,為何還要再將它集成到dynamic-datasource中?有兩方面原因:首先查刻,sharding-sphere原理是對sql語句進行改造键兜,然后路由到相應的數據源和表,這就導致它對某些sql語句不支持穗泵,比如distinct普气,在分庫分表的場景下就無法使用distinct關鍵字,但是對于未sharding的表佃延,也無法使用distinct现诀,這時候就可以使用dynamic-datasource來為未sharding的表做一個新的數據源夷磕;其次,某些系統(tǒng)仔沿,可能需要掛載很多數據庫(比如后臺管理系統(tǒng)需要掛載5個庫)坐桩,而其中只有1個庫涉及到sharding,而其他4個庫不涉及封锉,這時候就只能用dynamic-datasource來管理另外的4個庫和數據源绵跷。

代碼中有example,僅供參考成福。

Ref: https://www.cnblogs.com/jshen/p/7682502.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末碾局,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子奴艾,更是在濱河造成了極大的恐慌净当,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蕴潦,死亡現(xiàn)場離奇詭異像啼,居然都是意外死亡,警方通過查閱死者的電腦和手機潭苞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門埋合,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萄传,你說我怎么就攤上這事∶刍” “怎么了秀菱?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蹭睡。 經常有香客問我衍菱,道長,這世上最難降的妖魔是什么肩豁? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任脊串,我火速辦了婚禮,結果婚禮上清钥,老公的妹妹穿的比我還像新娘琼锋。我一直安慰自己,他們只是感情好祟昭,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布缕坎。 她就那樣靜靜地躺著,像睡著了一般篡悟。 火紅的嫁衣襯著肌膚如雪谜叹。 梳的紋絲不亂的頭發(fā)上匾寝,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天,我揣著相機與錄音荷腊,去河邊找鬼艳悔。 笑死,一個胖子當著我的面吹牛女仰,可吹牛的內容都是我干的猜年。 我是一名探鬼主播,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼董栽,長吁一口氣:“原來是場噩夢啊……” “哼码倦!你這毒婦竟也來了?” 一聲冷哼從身側響起锭碳,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤袁稽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后擒抛,有當地人在樹林里發(fā)現(xiàn)了一具尸體推汽,經...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年歧沪,在試婚紗的時候發(fā)現(xiàn)自己被綠了歹撒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡诊胞,死狀恐怖暖夭,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情撵孤,我是刑警寧澤迈着,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站邪码,受9級特大地震影響裕菠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜闭专,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一奴潘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧影钉,春花似錦画髓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春愚墓,著一層夾襖步出監(jiān)牢的瞬間予权,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工浪册, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留扫腺,地道東北人。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓村象,卻偏偏與公主長得像笆环,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子厚者,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內容