MySQL 分表後,真的就萬事大吉了嗎?

掃描下方海報二維碼,試聽課程:
面試

(課程詳細大綱,請參見文末)數據庫

文章轉自公衆號:crossoverJie架構

前言

本篇是上一篇《一次分表踩坑實踐的探討》,因此還沒看過的朋友建議先看上文。併發

仍是先來簡單回顧下上次提到了哪些內容:運維

  • 分表策略:哈希、時間歸檔等。分佈式

  • 分表字段的選擇。性能

  • 數據遷移方案。3d

而本篇文章的背景是在咱們上線這段時間遇到的一些問題並嘗試解決的方案。code

問題產生

以前提到在分表應用上線前咱們須要將原有表的數據遷移到新表中,這樣才能保證業務不受影響。orm

以下圖所示:

因此咱們單獨寫了一個遷移應用,它負責將大表中的數據遷移到 64 張分表,而再遷移過程當中產生的數據畢竟是少數,最後在上線當晚再次遷移過去便可。

一切想的很美好,當這個應用上線後卻發現沒這麼簡單。

數據庫負載升高

首先第一個問題是數據庫本身就頂不住了,在咱們上這個遷移程序以前數據庫的壓力自己就比較大,這個應用一上去就成了最後一根稻草。

最後致使的結果是:全部鏈接了數據庫的程序大部分的操做都出現超時,獲取不到數據庫鏈接等一系列的異常。

最後沒辦法咱們只能把這個應用放到凌晨執行,但其實後面觀察發現依然不行。

雖然說凌晨的業務量降低,但依然有少部分的請求過來,也會出現各類數據庫異常。

再一個是遷移程序的效率也很是低下,按照這樣是速度,咱們預估了一下遷移時間,大約須要 10 幾天才能把三張最大的表(三、4億的數據)遷移到分表中。

因而咱們換了一個方案,將這個遷移程序在從庫中運行,最後再用運維的方法將分表直接導入進主庫。

由於從庫的壓力要比主庫小不少,對業務的影響很小,同時遷移的效率也要快不少。

即使是這樣也花了一夜+一個白天的時間纔將一張 1億的數據遷移完成,可是業務上的壓力愈來愈大,數據量再不斷新增,這個效率依然不夠。

兼容方案

最終沒辦法只有想一個不遷移數據的方案,可是新產生的數據仍是往分表裏寫,至少保證大表的數據再也不新增。

但這樣對於之前的數據咋辦呢?總不能不讓看了吧。

其實對於數據的操做無非就分爲 增刪改查,就這四種操做來看看如何兼容。

新增

新增最簡單,全部的數據根據分表規則直接寫入新表,這樣能夠保證老表的數據再也不新增。

刪除

刪除就要比新增稍微複雜一些,好比用戶想要刪除他我的產生的一條信息(好比說是訂單數據),有可能這個數據在新表也可能在老表。

因此刪除時優先刪除新表(畢竟新產生的數據訪問的頻次越高),若是刪除失敗再從老表刪除一次。

修改

而修改同理,一樣的會不肯定數據存在於哪裏,因此先要修改新表,失敗後再次修改老表。

查詢

查詢相對就要複雜一些了,由於這些大表的數據大部分都是存放一個用戶產生的多條記錄(好比一個用戶的訂單信息)。

這時在頁面上一般都會有分頁,而且按照時間進行排序。

麻煩的地方就出在這裏:既然是要分頁那就有可能出現要查詢一部分分表數據和原來的大表數據作組合。

因此這裏的查詢其實分爲三種狀況,來看下面的圖:

  • 首先查詢的時候要計算這個用戶所在分表中的數據能夠分爲幾頁。

  • 第一步首先判斷當前頁是否能夠在分表中所有獲取,若是能夠則直接從分表中取出數據返回(假設分頁中總共能夠查詢 2 頁數據,當前爲第 1 頁,那就所有取分表數據)。

  • 若是不能夠就要判斷當前頁數在分表中是否取不到任何一條數據,若是是則直接取老表數據(好比如今要取第 5 頁的數據,分表中一共才只有 2 頁數據,因此第 5 頁數據只能所有從老表中獲取)。


  • 但若是分表和老表都存在一部分數據時,則須要同時取兩張表而後作一個彙總再返回。

這種邏輯只適用於根據分表字段進行查詢分頁的前提下

我想確定會有朋友提出這樣是否會有性能問題?

同時若是在計算分表分頁數量時出現併發寫入的狀況,致使分頁數量不許從而對後續的查詢出現影響該怎麼處理?

首先第一個性能問題:

其實這個要看怎麼取捨,爲了這樣的兼容目的其實會比常規查詢多出幾個步驟:

  • 判斷當前頁是否能夠在分表中查詢。

  • 當新老表中都有數據時候須要額外多查詢一張大表。

第一個判斷邏輯實際上是在內存中計算,這個損耗我以爲徹底能夠忽略不計。

至於第二步確實會有損耗,畢竟多查了一張表。

但在分表以前全部的數據都是從老表中獲取的,當時的業務也沒有出現問題;如今多的只是查詢分表而已,但分表的數據量確定要比大表小的多,並且有索引,因此這個效率也不會慢多少。

並且根據局部性原理及用戶的使用習慣來看,老表中的數據不多會去查詢,隨着時間的推移全部的數據確定都會從分表中獲取,逐漸老表就會成爲歷史表。

而第二個併發帶來的問題我以爲影響也不大,必定要這個分頁準的前提確定得是加鎖了,但爲了這樣一個不癢的小問題卻帶來性能的降低,我以爲是不划算的。

並且後續咱們也能夠慢慢的將老表的數據遷移到新表,這樣就能夠徹底去掉這個兼容邏輯了,全部的數據都從分表中獲取。

總結

仍是以前那句話,這裏的各類操做、方法不適合全部人,畢竟脫離場景都是耍牛氓。

好比分表搞的早,業務上容許必定的時間將數據遷移到分表那就不會有此次的兼容處理。

甚至一開始業務規劃合理、團隊架構師看的長遠,一來就將關鍵數據分表存儲那根本就不會有數據遷移這個流程(大廠有經驗的團隊可能,小公司小做坊都得靠本身摸索)。

這段期間也被數據庫折騰慘了,數據庫是最後一根稻草果真也不是瞎說的。



END


《21天互聯網Java進階面試訓練營(分佈式篇)》詳細目錄,掃描圖片末尾的二維碼,試聽課程

相關文章
相關標籤/搜索