一個挺著啤酒肚,身穿格子衫,髮際線嚴重後移的中年男子,手拿著保溫杯,胳膊夾著MacBook向你走來,看樣子是架構師級別。 面試開始,直入正題。 面試官: 小伙子,看到你的簡歷上面寫了項目中有對MySQL進行分庫分表,為什麼要進行分庫分表? 我: 不知道啊!誰知道老大咋想的,反正我來的時候就已經分好了 ...
一個挺著啤酒肚,身穿格子衫,髮際線嚴重後移的中年男子,手拿著保溫杯,胳膊夾著MacBook向你走來,看樣子是架構師級別。
面試開始,直入正題。
面試官: 小伙子,看到你的簡歷上面寫了項目中有對MySQL進行分庫分表,為什麼要進行分庫分表?
我: 不知道啊!誰知道老大咋想的,反正我來的時候就已經分好了。
面試官: 嗯...,今天的面試就先到這吧,有後續面試會通知你,我送你下去。
別啊,每次都說會通知我,然後我就傻傻的回去等通知了。我是實話實說,難道讓我去訂閱一燈的文章,背誦八股文給你聽?
好吧!自古真情留不住,總是套路得人心。重來一次,我把一燈總結的八股文背誦一遍。
我: 當MySQL單表數據量過大,比如超過5千萬條的時候,讀寫性能變得很差。而且常規的優化手段已經不起作用了,比如:SQL調優、添加索引、主從複製、讀寫分離。這時候就需要用到MySQL終極優化方案 — 分庫分表。
面試官: 不錯,我該怎麼判斷項目是需要分庫還是要分表?是先分庫還是先分表?
這誰能現場總結出來?彆著急,等我看一眼一燈的八股文。
我: 有了。
- 當資料庫的QPS過高,資料庫連接數不足的時候,就需要分庫。
- 當單表數據量過大,讀寫性能較差,就需要分表。
- 當兩者都有的時候,就需要分庫分表。
至於先分庫還是先分表?建議先分表,如果分表能解決問題,就不需要分庫了,畢竟需要單獨伺服器資源,成本更高。
面試官: 小伙子,總結的挺全。分庫分表有哪些拆分方案呢?
我: 分庫分表有垂直拆分和水平拆分。垂直拆分又有垂直分庫、垂直分表。
垂直分庫,不同的業務拆分到不同的資料庫。
垂直分表,把長度較大或者訪問頻次較低的欄位,拆分到擴展表中。
水平分表,單表數據量過大時,按照訂單ID拆分到多張表中。
面試官: 小伙子,有點東西。都知道分庫分表好使,就沒有什麼缺點嗎?
我: 當然有,“所有命運饋贈的禮物,早已在暗中標好了價格。”分庫分錶帶來了低耦合、高性能的優點,可是缺點卻是一大堆。
垂直分庫:
不同庫多表之間無法join關聯查詢,只能通過介面聚合,複雜度直線上升。
橫跨多個資料庫導致無法使用本地事務,數據強一致性就別想了,只能引入更為複雜的分散式事務,勉強實現數據的最終一致性,可用性直線下降。
垂直分表:
本來一張表能查出來的數據,現在需要多張表join關聯查詢,這不瞎耽誤事。
水平分表:
多張表關聯查詢時,無法實現分頁、排序功能。
面試官: 分庫分錶帶來這麼多問題,你沒有沒考慮過相應的解決方案?
我怎麼可能沒有解決方案,難道我提出問題給自己挖坑?
我: 當然有考慮過,“有問題就會有答案”。
跨庫查詢問題:
採用欄位冗餘方案,比如訂單表存儲店鋪ID、店鋪名稱,就不需要再查詢商戶資料庫了。
不過這種方案要求冗餘欄位要很少變動,就算變動後,也能容忍返回舊數據。
多表分頁查詢問題:
這個處理起來就很需要技術含量了。
比如:訂單表按照訂單ID分片,(order_id % 128),分成了128張表。
Leader看了說:每張表的數據量差不多,分的很均勻,以後不要再分了。
同一個用戶的訂單散落在不同的表,用戶想查詢自己的訂單,根本無法做到分頁查詢。難道一次全部查詢該用戶的所有訂單,然後做記憶體分頁,多大的機器記憶體都讓你搞掛。
想要實現用戶訂單分頁查詢,可以採用按照用戶ID分片,(user_id % 128),這樣同一個用戶的訂單隻會存儲在一張表中,咋分頁展示都行。
沒有完美的分片方案,如果商戶想要分頁查看自己店鋪的訂單怎麼辦?
那就把訂單再冗餘存儲一份,按照店鋪ID分片,(shop_id % 128)。不過由於商戶數量較少,可以搞個非同步線程往商戶訂單分片表同步。
訂單按照用戶ID分片後,發生數據傾斜怎麼辦?
因為不同用戶的訂單量是不同的,一個愛好購物的小姐姐的訂單量抵得上幾十個老爺們。導致一張表數據幾百條,另一張表數據量千萬級,這該咋整?
做冷熱數據分離,基礎庫只存儲3個月內的訂單,其他的移動到歷史訂單庫。這個要跟產品商量好,3個月前的訂單需要單獨的查詢頁面。
跨庫事務問題:
這個問題就更複雜了。
下一個訂單需要調用多個服務,只能使用分散式事務。
分散式事務的實現非常複雜,常用的有以下幾種解決方案:
二階段提交
TCC
本地消息表
MQ事務消息
分散式事務中間件
面試官: 準備的挺全啊。訂單表分片後,肯定不能使用資料庫自增主鍵做訂單ID,因為無法全局唯一,有什麼好的解決辦法?
我: 又問到我手心裡面,我前兩天剛看完一燈寫的“雪花演算法”,我現場手寫訂單ID的生成代碼吧。
面試官: 小伙子可以啊,下一面是HR面試,有薪資要求儘管提,你一定要來我們公司上班。
總結:
關於分庫分表的所有知識點,雖然很多,但都已經總結在這張圖上了。
文章持續更新,可以微信搜一搜「 一燈架構 」第一時間閱讀更多技術乾貨。