1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        如何設(shè)計(jì)可以動(dòng)態(tài)擴(kuò)容縮容的分庫分表方案?

        共 2476字,需瀏覽 5分鐘

         ·

        2022-03-16 09:44

        本文摘自 Doocs 開源社區(qū)《互聯(lián)網(wǎng) Java 工程師進(jìn)階知識(shí)完全掃盲》手冊(cè),方便讀者隨時(shí)隨地閱讀學(xué)習(xí)。

        也歡迎讀者們關(guān)注 GitHub 項(xiàng)目:https://github.com/doocs/advanced-java

        面試題

        如何設(shè)計(jì)可以動(dòng)態(tài)擴(kuò)容縮容的分庫分表方案?

        面試官心理分析

        對(duì)于分庫分表來說,主要是面對(duì)以下問題:

        ?選擇一個(gè)數(shù)據(jù)庫中間件,調(diào)研、學(xué)習(xí)、測試;?設(shè)計(jì)你的分庫分表的一個(gè)方案,你要分成多少個(gè)庫,每個(gè)庫分成多少個(gè)表,比如 3 個(gè)庫,每個(gè)庫 4 個(gè)表;?基于選擇好的數(shù)據(jù)庫中間件,以及在測試環(huán)境建立好的分庫分表的環(huán)境,然后測試一下能否正常進(jìn)行分庫分表的讀寫;?完成單庫單表到分庫分表的遷移,雙寫方案;?線上系統(tǒng)開始基于分庫分表對(duì)外提供服務(wù);?擴(kuò)容了,擴(kuò)容成 6 個(gè)庫,每個(gè)庫需要 12 個(gè)表,你怎么來增加更多庫和表呢?

        這個(gè)是你必須面對(duì)的一個(gè)事兒,就是你已經(jīng)弄好分庫分表方案了,然后一堆庫和表都建好了,基于分庫分表中間件的代碼開發(fā)啥的都好了,測試都 ok 了,數(shù)據(jù)能均勻分布到各個(gè)庫和各個(gè)表里去,而且接著你還通過雙寫的方案咔嚓一下上了系統(tǒng),已經(jīng)直接基于分庫分表方案在搞了。

        那么現(xiàn)在問題來了,你現(xiàn)在這些庫和表又支撐不住了,要繼續(xù)擴(kuò)容咋辦?這個(gè)可能就是說你的每個(gè)庫的容量又快滿了,或者是你的表數(shù)據(jù)量又太大了,也可能是你每個(gè)庫的寫并發(fā)太高了,你得繼續(xù)擴(kuò)容。

        這都是玩兒分庫分表線上必須經(jīng)歷的事兒。

        面試題剖析

        停機(jī)擴(kuò)容(不推薦)

        這個(gè)方案就跟停機(jī)遷移一樣,步驟幾乎一致,唯一的一點(diǎn)就是那個(gè)導(dǎo)數(shù)的工具,是把現(xiàn)有庫表的數(shù)據(jù)抽出來慢慢倒入到新的庫和表里去。但是最好別這么玩兒,有點(diǎn)不太靠譜,因?yàn)榧热?strong style="line-height: 1.75;color: rgb(207, 14, 85);">分庫分表就說明數(shù)據(jù)量實(shí)在是太大了,可能多達(dá)幾億條,甚至幾十億,你這么玩兒,可能會(huì)出問題。

        從單庫單表遷移到分庫分表的時(shí)候,數(shù)據(jù)量并不是很大,單表最大也就兩三千萬。那么你寫個(gè)工具,多弄幾臺(tái)機(jī)器并行跑,1 小時(shí)數(shù)據(jù)就導(dǎo)完了。這沒有問題。

        如果 3 個(gè)庫 + 12 個(gè)表,跑了一段時(shí)間了,數(shù)據(jù)量都 1~2 億了。光是導(dǎo) 2 億數(shù)據(jù),都要導(dǎo)個(gè)幾個(gè)小時(shí),6 點(diǎn),剛剛導(dǎo)完數(shù)據(jù),還要搞后續(xù)的修改配置,重啟系統(tǒng),測試驗(yàn)證,10 點(diǎn)才可以搞完。所以不能這么搞。

        優(yōu)化后的方案

        一開始上來就是 32 個(gè)庫,每個(gè)庫 32 個(gè)表,那么總共是 1024 張表。

        我可以告訴各位同學(xué),這個(gè)分法,第一,基本上國內(nèi)的互聯(lián)網(wǎng)肯定都是夠用了,第二,無論是并發(fā)支撐還是數(shù)據(jù)量支撐都沒問題。

        每個(gè)庫正常承載的寫入并發(fā)量是 1000,那么 32 個(gè)庫就可以承載 32 _ 1000 = 32000 的寫并發(fā),如果每個(gè)庫承載 1500 的寫并發(fā),32 _ 1500 = 48000 的寫并發(fā),接近 5 萬每秒的寫入并發(fā),前面再加一個(gè) MQ,削峰,每秒寫入 MQ 8 萬條數(shù)據(jù),每秒消費(fèi) 5 萬條數(shù)據(jù)。

        有些除非是國內(nèi)排名非??壳暗倪@些公司,他們的最核心的系統(tǒng)的數(shù)據(jù)庫,可能會(huì)出現(xiàn)幾百臺(tái)數(shù)據(jù)庫的這么一個(gè)規(guī)模,128 個(gè)庫,256 個(gè)庫,512 個(gè)庫。

        1024 張表,假設(shè)每個(gè)表放 500 萬數(shù)據(jù),在 MySQL 里可以放 50 億條數(shù)據(jù)。

        每秒 5 萬的寫并發(fā),總共 50 億條數(shù)據(jù),對(duì)于國內(nèi)大部分的互聯(lián)網(wǎng)公司來說,其實(shí)一般來說都?jí)蛄恕?/p>

        談分庫分表的擴(kuò)容,第一次分庫分表,就一次性給他分個(gè)夠,32 個(gè)庫,1024 張表,可能對(duì)大部分的中小型互聯(lián)網(wǎng)公司來說,已經(jīng)可以支撐好幾年了。

        一個(gè)實(shí)踐是利用?32 * 32?來分庫分表,即分為 32 個(gè)庫,每個(gè)庫里一個(gè)表分為 32 張表。一共就是 1024 張表。根據(jù)某個(gè) id 先根據(jù) 32 取模路由到庫,再根據(jù) 32 取模路由到庫里的表。

        orderIdid % 32 (庫)id / 32 % 32 (表)
        25938
        118955
        352011
        45931715

        剛開始的時(shí)候,這個(gè)庫可能就是邏輯庫,建在一個(gè)數(shù)據(jù)庫上的,就是一個(gè) MySQL 服務(wù)器可能建了 n 個(gè)庫,比如 32 個(gè)庫。后面如果要拆分,就是不斷在庫和 MySQL 服務(wù)器之間做遷移就可以了。然后系統(tǒng)配合改一下配置即可。

        比如說最多可以擴(kuò)展到 32 個(gè)數(shù)據(jù)庫服務(wù)器,每個(gè)數(shù)據(jù)庫服務(wù)器是一個(gè)庫。如果還是不夠?最多可以擴(kuò)展到 1024 個(gè)數(shù)據(jù)庫服務(wù)器,每個(gè)數(shù)據(jù)庫服務(wù)器上面一個(gè)庫一個(gè)表。因?yàn)樽疃嗍?1024 個(gè)表。

        這么搞,是不用自己寫代碼做數(shù)據(jù)遷移的,都交給 DBA 來搞好了,但是 DBA 確實(shí)是需要做一些庫表遷移的工作,但是總比你自己寫代碼,然后抽數(shù)據(jù)導(dǎo)數(shù)據(jù)來的效率高得多吧。

        哪怕是要減少庫的數(shù)量,也很簡單,其實(shí)說白了就是按倍數(shù)縮容就可以了,然后修改一下路由規(guī)則。

        這里對(duì)步驟做一個(gè)總結(jié):

        1.設(shè)定好幾臺(tái)數(shù)據(jù)庫服務(wù)器,每臺(tái)服務(wù)器上幾個(gè)庫,每個(gè)庫多少個(gè)表,推薦是 32 庫 * 32 表,對(duì)于大部分公司來說,可能幾年都?jí)蛄恕?/span>2.路由的規(guī)則,orderId 模 32 = 庫,orderId / 32 模 32 = 表3.擴(kuò)容的時(shí)候,申請(qǐng)?jiān)黾痈嗟臄?shù)據(jù)庫服務(wù)器,裝好 MySQL,呈倍數(shù)擴(kuò)容,4 臺(tái)服務(wù)器,擴(kuò)到 8 臺(tái)服務(wù)器,再到 16 臺(tái)服務(wù)器。4.由 DBA 負(fù)責(zé)將原先數(shù)據(jù)庫服務(wù)器的庫,遷移到新的數(shù)據(jù)庫服務(wù)器上去,庫遷移是有一些便捷的工具的。5.我們這邊就是修改一下配置,調(diào)整遷移的庫所在數(shù)據(jù)庫服務(wù)器的地址。6.重新發(fā)布系統(tǒng),上線,原先的路由規(guī)則變都不用變,直接可以基于 n 倍的數(shù)據(jù)庫服務(wù)器的資源,繼續(xù)進(jìn)行線上系統(tǒng)的提供服務(wù)。

        推薦閱讀

        ?分庫分表之后,id 主鍵如何處理??MySQL 主從同步延時(shí)問題與解決方案?MQ 消息重復(fù)消費(fèi)問題與解決方案?MQ 消息丟失問題與解決方案?MQ 消息錯(cuò)亂問題與解決方案


        歡迎關(guān)注公眾號(hào)「Doocs」,第一時(shí)間跟你們分享好玩、實(shí)用的技術(shù)文章與業(yè)內(nèi)最新資訊。



        瀏覽 26
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            九九热免费视频在线观看 | 激情婷婷丁香五月 | 理论av| 久久久久久国产精品火龙果影视 | 逼逼爱插插网 | 亚洲午夜精品久久久 | 亚洲精品乱码久久久久久蜜桃91 | 欧美午夜福利视频 | 国产又爽 又黄 免费动漫 | 国产人人插|