1. 程式人生 > >[資料庫]-----記一次mysql分庫的操作(冷熱分離)

[資料庫]-----記一次mysql分庫的操作(冷熱分離)

前提:

1.原有庫是mysql資料庫,已經根據使用者pin分片
2.每片是一主兩從
3.主表已經分過表了
4.資料庫所在伺服器為4C8G
5.庫中資料量已經超過千萬,而且以每天3萬多的資料持續增長,將來每天或許會更多
6.庫內資料為訂單資料,每時每刻都有新的訂單產生,每個訂單都要經歷多個狀態的變化,最終變成完成狀態,每次變化狀態,都會對資料庫進行修改

正題:

現在這樣的資料庫,其實是完全可以支援現有業務,但考慮到以後隨著資料量的日益增長,每次查詢都要在千萬資料中查詢,但其實大部分查詢,都是查最近的資料,歷史資料幾乎不查詢,基於這個條件,就考慮到可以做個分庫,也就是冷熱分離。

所謂冷熱分離,網上有很多說法,而我之所以做冷熱分離,最終目的,就是為了將經常使用查詢的資料放在生產庫中,而查詢不多的歷史資料就放在歷史庫中,這樣既可以保證資料的完整,也可以減輕生產庫的壓力。

既然有這樣的分庫查詢,那就涉及到兩個庫的資料同步(這裡叫生產庫和歷史庫)
生產庫放的是熱資料,歷史課放冷資料

正常下單後,訂單資料還是新增到生產庫中,但是每次資料在生產庫的變化,都會多發一個mq出去,mq中帶有這個訂單資料的唯一主鍵和訂單所改變的狀態

歷史庫接收到這個mq,再反查生產庫,獲得這條資料,然後在歷史庫做相應的狀態更改,這樣就可以保證歷史庫和生產庫的資料統一

如下圖:

這裡寫圖片描述

對於生產庫,原則上只保留500萬左右的熱資料,其餘歷史資料,全部放在歷史庫,這樣又會有兩個重點:資料遷移和多資料來源的查詢

1.資料遷移

以下提供幾種資料遷移的思路
1.1.執行一個job,定時每天凌晨開始自動遷移,每次遷移若干條,這樣就會在不知不覺中將資料遷移完,這樣最保險,但不是效率最高
1.2.直接用一個執行緒池,最多開五個執行緒(具體能開幾個,看自己的機器效能),然後每個執行緒每次只跑一天的量,這樣其實也是很快的

2.多資料來源的查詢

有了兩個資料來源,那麼什麼時候查生產庫,什麼時候查歷史庫就是需要考慮的一個問題,我這邊完全是業務方面的區分,這裡只提一嘴,供參考
2.1.針對單條資料的查詢,單條資料的查詢一般發生在剛剛下單後,所以優先查詢生產庫,生產庫沒有,再去查詢歷史庫。
2.2.針對某一時間段內,多條資料查詢list,這裡我們可以預先定義一個分割線,這個分割線是一個日期,這個日期就是生產庫最早一條資料的日期,有了這個分割線,那我們只需要拿要查詢的日期區間和這個分割線做比較,即可確定
2.3.針對多個分散訂單的查詢list,理論上沒有任何規律,但是由於歷史資料發現,這種情況一般有數量不多,資料多在近期的特徵,所以還是優先查詢生產庫,查不到再查詢歷史庫

思考

這個冷熱分離的好處,就是將不常用的資料放在歷史庫中,當然,這個歷史庫也可以是多個,也就是一個生產庫,多個歷史庫,每個歷史庫都存放某一時間段的資料

擴充套件

作為思考,如果以後每天的資料量都很大,我將考慮在資料庫之前加一層快取,比如用redis等非關係型資料庫,或者用es,因為以前也嘗試過用這樣的方式來緩解資料庫的壓力,但發現會存在低機率的資料丟失,所以在這些又會涉及到資料的準確性,資料的即時同步將會是一個很大的挑戰,但這應該是現有技術中,對於上億級別的資料即使查詢,比較好的方式了