為什么要分庫分表(設計高并發(fā)系統(tǒng)的時候启摄,數(shù)據(jù)庫層面該如何設計)?用過哪些分庫分表中間件幽钢?不同的分庫分表中間件都有什么優(yōu)點和缺點歉备?你們具體是如何對數(shù)據(jù)庫如何進行垂直拆分或水平拆分的?

原文出處:https://github.com/doocs/advanced-java/blob/master/docs/high-concurrency/database-shard.md
歡迎 star 關注 GitHub 項目最新動態(tài)匪燕!

面試題

為什么要分庫分表(設計高并發(fā)系統(tǒng)的時候蕾羊,數(shù)據(jù)庫層面該如何設計)?用過哪些分庫分表中間件帽驯?不同的分庫分表中間件都有什么優(yōu)點和缺點龟再?你們具體是如何對數(shù)據(jù)庫如何進行垂直拆分或水平拆分的?

面試官心理分析

其實這塊肯定是扯到高并發(fā)了尼变,因為分庫分表一定是為了支撐高并發(fā)利凑、數(shù)據(jù)量大兩個問題的。而且現(xiàn)在說實話嫌术,尤其是互聯(lián)網類的公司面試哀澈,基本上都會來這么一下,分庫分表如此普遍的技術問題度气,不問實在是不行割按,而如果你不知道那也實在是說不過去!

面試題剖析

為什么要分庫分表磷籍?(設計高并發(fā)系統(tǒng)的時候适荣,數(shù)據(jù)庫層面該如何設計?)

說白了院领,分庫分表是兩回事兒弛矛,大家可別搞混了,可能是光分庫不分表栅盲,也可能是光分表不分庫汪诉,都有可能。

我先給大家拋出來一個場景谈秫。

假如我們現(xiàn)在是一個小創(chuàng)業(yè)公司(或者是一個 BAT 公司剛興起的一個新部門)扒寄,現(xiàn)在注冊用戶就 20 萬,每天活躍用戶就 1 萬拟烫,每天單表數(shù)據(jù)量就 1000该编,然后高峰期每秒鐘并發(fā)請求最多就 10。天硕淑,就這種系統(tǒng)课竣,隨便找一個有幾年工作經驗的嘉赎,然后帶幾個剛培訓出來的,隨便干干都可以于樟。

結果沒想到我們運氣居然這么好公条,碰上個 CEO 帶著我們走上了康莊大道,業(yè)務發(fā)展迅猛迂曲,過了幾個月靶橱,注冊用戶數(shù)達到了 2000 萬!每天活躍用戶數(shù) 100 萬路捧!每天單表數(shù)據(jù)量 10 萬條关霸!高峰期每秒最大請求達到 1000!同時公司還順帶著融資了兩輪杰扫,進賬了幾個億人民幣岸涌堋!公司估值達到了驚人的幾億美金章姓!這是小獨角獸的節(jié)奏佳遣!

好吧,沒事啤覆,現(xiàn)在大家感覺壓力已經有點大了苍日,為啥呢?因為每天多 10 萬條數(shù)據(jù)窗声,一個月就多 300 萬條數(shù)據(jù)相恃,現(xiàn)在咱們單表已經幾百萬數(shù)據(jù)了,馬上就破千萬了笨觅。但是勉強還能撐著拦耐。高峰期請求現(xiàn)在是 1000,咱們線上部署了幾臺機器见剩,負載均衡搞了一下杀糯,數(shù)據(jù)庫撐 1000QPS 也還湊合。但是大家現(xiàn)在開始感覺有點擔心了苍苞,接下來咋整呢......

再接下來幾個月固翰,我的天,CEO 太牛逼了羹呵,公司用戶數(shù)已經達到 1 億骂际,公司繼續(xù)融資幾十億人民幣啊冈欢!公司估值達到了驚人的幾十億美金歉铝,成為了國內今年最牛逼的明星創(chuàng)業(yè)公司!天凑耻,我們太幸運了太示。

但是我們同時也是不幸的柠贤,因為此時每天活躍用戶數(shù)上千萬,每天單表新增數(shù)據(jù)多達 50 萬类缤,目前一個表總數(shù)據(jù)量都已經達到了兩三千萬了臼勉!扛不住啊呀非!數(shù)據(jù)庫磁盤容量不斷消耗掉坚俗!高峰期并發(fā)達到驚人的 5000~8000!別開玩笑了岸裙,哥。我跟你保證速缆,你的系統(tǒng)支撐不到現(xiàn)在降允,已經掛掉了!

好吧艺糜,所以你看到這里差不多就理解分庫分表是怎么回事兒了剧董,實際上這是跟著你的公司業(yè)務發(fā)展走的,你公司業(yè)務發(fā)展越好破停,用戶就越多翅楼,數(shù)據(jù)量越大,請求量越大真慢,那你單個數(shù)據(jù)庫一定扛不住毅臊。

分表

比如你單表都幾千萬數(shù)據(jù)了,你確定你能扛住么黑界?絕對不行管嬉,單表數(shù)據(jù)量太大,會極大影響你的 sql 執(zhí)行的性能朗鸠,到了后面你的 sql 可能就跑的很慢了蚯撩。一般來說,就以我的經驗來看烛占,單表到幾百萬的時候胎挎,性能就會相對差一些了,你就得分表了忆家。

分表是啥意思犹菇?就是把一個表的數(shù)據(jù)放到多個表中,然后查詢的時候你就查一個表弦赖。比如按照用戶 id 來分表项栏,將一個用戶的數(shù)據(jù)就放在一個表中。然后操作的時候你對一個用戶就操作那個表就好了蹬竖。這樣可以控制每個表的數(shù)據(jù)量在可控的范圍內沼沈,比如每個表就固定在 200 萬以內流酬。

分庫

分庫是啥意思?就是你一個庫一般我們經驗而言列另,最多支撐到并發(fā) 2000芽腾,一定要擴容了,而且一個健康的單庫并發(fā)值你最好保持在每秒 1000 左右页衙,不要太大摊滔。那么你可以將一個庫的數(shù)據(jù)拆分到多個庫中,訪問的時候就訪問一個庫好了店乐。

這就是所謂的分庫分表艰躺,為啥要分庫分表?你明白了吧眨八。

# 分庫分表前 分庫分表后
并發(fā)支撐情況 MySQL 單機部署腺兴,扛不住高并發(fā) MySQL從單機到多機,能承受的并發(fā)增加了多倍
磁盤使用情況 MySQL 單機磁盤容量幾乎撐滿 拆分為多個庫廉侧,數(shù)據(jù)庫服務器磁盤使用率大大降低
SQL 執(zhí)行性能 單表數(shù)據(jù)量太大页响,SQL 越跑越慢 單表數(shù)據(jù)量減少,SQL 執(zhí)行效率明顯提升

用過哪些分庫分表中間件段誊?不同的分庫分表中間件都有什么優(yōu)點和缺點闰蚕?

這個其實就是看看你了解哪些分庫分表的中間件,各個中間件的優(yōu)缺點是啥连舍?然后你用過哪些分庫分表的中間件没陡。

比較常見的包括:

  • Cobar
  • TDDL
  • Atlas
  • Sharding-jdbc
  • Mycat

Cobar

阿里 b2b 團隊開發(fā)和開源的,屬于 proxy 層方案烟瞧,就是介于應用服務器和數(shù)據(jù)庫服務器之間诗鸭。應用程序通過 JDBC 驅動訪問 Cobar 集群,Cobar 根據(jù) SQL 和分庫規(guī)則對 SQL 做分解参滴,然后分發(fā)到 MySQL 集群不同的數(shù)據(jù)庫實例上執(zhí)行强岸。早些年還可以用,但是最近幾年都沒更新了砾赔,基本沒啥人用蝌箍,差不多算是被拋棄的狀態(tài)吧。而且不支持讀寫分離暴心、存儲過程妓盲、跨庫 join 和分頁等操作。

TDDL

淘寶團隊開發(fā)的专普,屬于 client 層方案悯衬。支持基本的 crud 語法和讀寫分離,但不支持 join檀夹、多表查詢等語法筋粗。目前使用的也不多策橘,因為還依賴淘寶的 diamond 配置管理系統(tǒng)。

Atlas

360 開源的娜亿,屬于 proxy 層方案丽已,以前是有一些公司在用的,但是確實有一個很大的問題就是社區(qū)最新的維護都在 5 年前了买决。所以沛婴,現(xiàn)在用的公司基本也很少了。

Sharding-jdbc

當當開源的督赤,屬于 client 層方案嘁灯,目前已經更名為 ShardingSphere(后文所提到的 Sharding-jdbc,等同于 ShardingSphere)躲舌。確實之前用的還比較多一些旁仿,因為 SQL 語法支持也比較多,沒有太多限制孽糖,而且截至 2019.4,已經推出到了 4.0.0-RC1 版本毅贮,支持分庫分表办悟、讀寫分離、分布式 id 生成滩褥、柔性事務(最大努力送達型事務病蛉、TCC 事務)。而且確實之前使用的公司會比較多一些(這個在官網有登記使用的公司瑰煎,可以看到從 2017 年一直到現(xiàn)在铺然,是有不少公司在用的)零抬,目前社區(qū)也還一直在開發(fā)和維護倍谜,還算是比較活躍狡忙,個人認為算是一個現(xiàn)在也可以選擇的方案昆庇。

Mycat

基于 Cobar 改造的吃溅,屬于 proxy 層方案迁杨,支持的功能非常完善啦租,而且目前應該是非持晾剩火的而且不斷流行的數(shù)據(jù)庫中間件农尖,社區(qū)很活躍析恋,也有一些公司開始在用了。但是確實相比于 Sharding jdbc 來說盛卡,年輕一些助隧,經歷的錘煉少一些。

總結

綜上滑沧,現(xiàn)在其實建議考量的并村,就是 Sharding-jdbc 和 Mycat巍实,這兩個都可以去考慮使用。

Sharding-jdbc 這種 client 層方案的優(yōu)點在于不用部署橘霎,運維成本低蔫浆,不需要代理層的二次轉發(fā)請求,性能很高姐叁,但是如果遇到升級啥的需要各個系統(tǒng)都重新升級版本再發(fā)布瓦盛,各個系統(tǒng)都需要耦合 Sharding-jdbc 的依賴;

Mycat 這種 proxy 層方案的缺點在于需要部署外潜,自己運維一套中間件原环,運維成本高,但是好處在于對于各個項目是透明的处窥,如果遇到升級之類的都是自己中間件那里搞就行了嘱吗。

通常來說,這兩個方案其實都可以選用滔驾,但是我個人建議中小型公司選用 Sharding-jdbc谒麦,client 層方案輕便,而且維護成本低哆致,不需要額外增派人手绕德,而且中小型公司系統(tǒng)復雜度會低一些,項目也沒那么多摊阀;但是中大型公司最好還是選用 Mycat 這類 proxy 層方案耻蛇,因為可能大公司系統(tǒng)和項目非常多,團隊很大胞此,人員充足臣咖,那么最好是專門弄個人來研究和維護 Mycat,然后大量項目直接透明使用即可漱牵。

你們具體是如何對數(shù)據(jù)庫如何進行垂直拆分或水平拆分的夺蛇?

水平拆分的意思,就是把一個表的數(shù)據(jù)給弄到多個庫的多個表里去布疙,但是每個庫的表結構都一樣蚊惯,只不過每個庫表放的數(shù)據(jù)是不同的,所有庫表的數(shù)據(jù)加起來就是全部數(shù)據(jù)灵临。水平拆分的意義截型,就是將數(shù)據(jù)均勻放更多的庫里,然后用多個庫來扛更高的并發(fā)儒溉,還有就是用多個庫的存儲容量來進行擴容宦焦。

database-split-horizon

垂直拆分的意思,就是把一個有很多字段的表給拆分成多個表或者是多個庫上去波闹。每個庫表的結構都不一樣酝豪,每個庫表都包含部分字段。一般來說精堕,會將較少的訪問頻率很高的字段放到一個表里去孵淘,然后將較多的訪問頻率很低的字段放到另外一個表里去。因為數(shù)據(jù)庫是有緩存的歹篓,你訪問頻率高的行字段越少瘫证,就可以在緩存里緩存更多的行,性能就越好庄撮。這個一般在表層面做的較多一些背捌。

database-split-vertically.png

這個其實挺常見的,不一定我說洞斯,大家很多同學可能自己都做過毡庆,把一個大表拆開,訂單表烙如、訂單支付表么抗、訂單商品表。

還有表層面的拆分亚铁,就是分表乖坠,將一個表變成 N 個表,就是讓每個表的數(shù)據(jù)量控制在一定范圍內刀闷,保證 SQL 的性能。否則單表數(shù)據(jù)量越大仰迁,SQL 性能就越差甸昏。一般是 200 萬行左右,不要太多徐许,但是也得看具體你怎么操作施蜜,也可能是 500 萬,或者是 100 萬雌隅。你的SQL越復雜翻默,就最好讓單表行數(shù)越少。

好了恰起,無論分庫還是分表修械,上面說的那些數(shù)據(jù)庫中間件都是可以支持的。就是基本上那些中間件可以做到你分庫分表之后检盼,中間件可以根據(jù)你指定的某個字段值肯污,比如說 userid,自動路由到對應的庫上去,然后再自動路由到對應的表里去蹦渣。

你就得考慮一下哄芜,你的項目里該如何分庫分表?一般來說柬唯,垂直拆分认臊,你可以在表層面來做,對一些字段特別多的表做一下拆分锄奢;水平拆分失晴,你可以說是并發(fā)承載不了,或者是數(shù)據(jù)量太大斟薇,容量承載不了师坎,你給拆了,按什么字段來拆堪滨,你自己想好胯陋;分表,你考慮一下袱箱,你如果哪怕是拆到每個庫里去遏乔,并發(fā)和容量都 ok 了,但是每個庫的表還是太大了发笔,那么你就分表盟萨,將這個表分開,保證每個表的數(shù)據(jù)量并不是很大了讨。

而且這兒還有兩種分庫分表的方式

  • 一種是按照 range 來分捻激,就是每個庫一段連續(xù)的數(shù)據(jù),這個一般是按比如時間范圍來的前计,但是這種一般較少用胞谭,因為很容易產生熱點問題,大量的流量都打在最新的數(shù)據(jù)上了男杈。
  • 或者是按照某個字段 hash 一下均勻分散丈屹,這個較為常用。

range 來分伶棒,好處在于說旺垒,擴容的時候很簡單,因為你只要預備好肤无,給每個月都準備一個庫就可以了先蒋,到了一個新的月份的時候,自然而然宛渐,就會寫新的庫了鞭达;缺點司忱,但是大部分的請求,都是訪問最新的數(shù)據(jù)畴蹭。實際生產用 range坦仍,要看場景。

hash 分發(fā)叨襟,好處在于說繁扎,可以平均分配每個庫的數(shù)據(jù)量和請求壓力;壞處在于說擴容起來比較麻煩糊闽,會有一個數(shù)據(jù)遷移的過程梳玫,之前的數(shù)據(jù)需要重新計算 hash 值重新分配到不同的庫或表。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末右犹,一起剝皮案震驚了整個濱河市提澎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌念链,老刑警劉巖盼忌,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掂墓,居然都是意外死亡谦纱,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門君编,熙熙樓的掌柜王于貴愁眉苦臉地迎上來跨嘉,“玉大人,你說我怎么就攤上這事吃嘿§裟耍” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵兑燥,是天一觀的道長跳纳。 經常有香客問我,道長贪嫂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任艾蓝,我火速辦了婚禮力崇,結果婚禮上,老公的妹妹穿的比我還像新娘赢织。我一直安慰自己亮靴,他們只是感情好,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布于置。 她就那樣靜靜地躺著茧吊,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搓侄,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天瞄桨,我揣著相機與錄音,去河邊找鬼讶踪。 笑死芯侥,一個胖子當著我的面吹牛,可吹牛的內容都是我干的乳讥。 我是一名探鬼主播柱查,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼云石!你這毒婦竟也來了唉工?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤汹忠,失蹤者是張志新(化名)和其女友劉穎淋硝,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體错维,經...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡奖地,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赋焕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片参歹。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖隆判,靈堂內的尸體忽然破棺而出犬庇,到底是詐尸還是另有隱情,我是刑警寧澤侨嘀,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布臭挽,位于F島的核電站,受9級特大地震影響咬腕,放射性物質發(fā)生泄漏欢峰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一涨共、第九天 我趴在偏房一處隱蔽的房頂上張望纽帖。 院中可真熱鬧,春花似錦举反、人聲如沸懊直。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽室囊。三九已至雕崩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間融撞,已是汗流浹背盼铁。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留懦铺,地道東北人捉貌。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像冬念,于是被迫代替她去往敵國和親趁窃。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容