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

面試官心理分析

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

1.選擇一個(gè)數(shù)據(jù)庫中間件,調(diào)研、學(xué)習(xí)、測(cè)試;

2.設(shè)計(jì)你的分庫分表的一個(gè)方案,你要分成多少個(gè)庫,每個(gè)庫分成多少個(gè)表,比如 3 個(gè)庫,每個(gè)庫 4 個(gè)表;

3.基于選擇好的數(shù)據(jù)庫中間件,以及在測(cè)試環(huán)境建立好的分庫分表的環(huán)境,然后測(cè)試一下能否正常進(jìn)行分庫分表的讀寫;

4.完成單庫單表到分庫分表的遷移,雙寫方案;

5.線上系統(tǒng)開始基于分庫分表對(duì)外提供服務(wù);

6.擴(kuò)容了,擴(kuò)容成 6 個(gè)庫,每個(gè)庫需要 12 個(gè)表,你怎么來增加更多庫和表呢?

這個(gè)是你必須面對(duì)的一個(gè)事兒,就是你已經(jīng)弄好分庫分表方案了,然后一堆庫和表都建好了,基于分庫分表中間件的代碼開發(fā)啥的都好了,測(cè)試都 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)榧热环謳旆直砭驼f明數(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),測(cè)試驗(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 取模路由到庫里的表。


剛開始的時(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í)蛄恕?/p>

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ù)。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容