Hello,大家好,我是樓下小黑哥~
随着業務的快速增長,業務體量變得越來越大,這個過程我們會碰到各種問題,倒逼着我們進行技術更新。
那今天我們來聊下,這個過程将會碰到關于資料的問題。
資料增長帶來的煩惱
業務快速增長,業務表資料記錄不斷在增加,這就會帶來兩個問題。
第一,資料庫資料最終将會儲存在本地磁盤中,資料記錄越多,磁盤占用空間就會越多,對應剩餘可用空間就會越少。
剩餘空間到達一定的門檻值之後,将會引發磁盤空間的持續報警,消耗寶貴的資料庫生産伺服器的資源。
第二,業務表記錄越多,表查詢的效率就會相應變低,另外表變更也會變的很麻煩。
那解決這個問題,解決辦法有很多,那 今天介紹其中一種方式,資料歸檔。
資料歸檔
資料歸檔的解決思路非常簡單,就是将生産庫的資料轉移到擁有相同表結構的資料庫中,通過減少生産庫記錄數量,進而提高資料查詢等操作的效率。
資料歸檔的流程如圖所示:
資料歸檔分為三個流程
- 建立一個新的資料庫-歸檔庫,然後在歸檔庫建立與生産庫相同的表
- 不斷查詢生産庫資料記錄,同步複制到歸檔庫
- 生産庫删除已經複制的資料記錄
雖然資料資料歸檔流程非常簡單,但是設計資料歸檔的方案,我們必須想清楚以下幾個問題:
- 歸檔前:那些資料可以歸檔?歸檔庫如何選型?
- 歸檔中:資料歸檔的執行方案
- 歸檔後:資料歸檔帶來問題預案
歸檔之前
首先我們需要思考第一個問題,那些資料可以歸檔?
表資料量很大,并且存在很明顯的冷熱資料,冷資料幾乎很少通路。
一個非常典型的例子,訂單資料。我們通常通路最近的曆史訂單,而一年前的曆史訂單檢視就會很少。
又比如優惠券資料,還未過期的優惠券,可能需要被查詢使用。而一年前過期的,或者說已經被使用的優惠券,就會被很少通路。
是以,設計資料歸檔的之前,我們需要思考,我們歸檔的資料是否适合被歸檔。
第二,我們需要思考歸檔資料庫的選型。
資料歸檔主要目的是為了節約寶貴的生産伺服器存儲,資料需要經過壓縮後才會存到資料庫。
是以,歸檔庫需要選擇那些支援高壓縮比的存儲引擎。
我們目前歸檔庫選型使用 TokuDB 引擎的 MySQL資料庫,壓縮比大約為6:1。
歸檔之中
上面流程我們看到,資料歸檔無非就是查詢資料,插入資料,然後删除資料。
那我們可以基于這個流程開發一個通用的歸檔腳本。
Google 搜尋了一圈,在 Github 上找到了一個歸檔小工具,基本上實作了資料歸檔的自動運轉,統一的歸檔任務排程管理、自動監控和預警、自動生成報表。在一定程度上節約了生産力,提高了運維效率。
github位址:https://github.com/dbarun/mysql_archiver
特殊歸檔需求
一般來說,通用資料歸檔腳本可以滿足大部分情況。但是如果資料歸檔有一些特殊的要求的話,那就需要自己開發。
比如說,我們有一個項目,資料歸檔的需求是批量查詢 90 天前的資料,然後将這些資料插入到當年的歸檔表中。
舉個例子,如果目前資料記錄建立時間為 2020-12-31,這個記錄将會歸檔到 archive_2020 表中。
那如果這個資料記錄建立時間為 2021-01-01,那這個記錄就會被歸檔到 archive_2021 表中。
那像這種有明顯業務需求資料歸檔方式,那就需要我們在項目中自己開發。
歸檔注意事項
第一,資料歸檔過程需要不斷的讀寫生産庫,這個過程将會大量使用的網絡、IO。那為了防止對線上業務造成壓力,資料歸檔一般隻在業務低峰期執行。
另外我們需要盡可能調優資料,盡量降低對線上業務的影響。
第二,資料歸檔之後,将會删除生産庫的資料,這些資料删除之後,将會造成資料空洞。即資料删除之後,表空間并未及時的釋放,當長時間沒有新的資料填充,會造成空間浪費的情況。
是以資料删除之後,我們需要及時優化資料空洞,釋放這些被浪費的空間。
第三,如果資料歸檔中,影響了線上業務,那一定要及時止損,結束資料歸檔,然後複盤問題,及時找到問題。
歸檔之後
資料歸檔之後,将會帶來一些問題,我們需要及時想好這些的預案。
資料幂等被破壞
生産資料庫,我們可以使用唯一索引,防止插入重複資料。
但是資料歸檔之後,部分資料被歸檔到歸檔庫,這樣生産庫就又可以插入這些資料庫,這就會造成業務上插入重複的資料。
那這個問題,我們可以使用 ID 發号器解決。生産資料庫唯一索引存儲 ID 發号生成的 ID,ID 發号器每天單調遞增,那理論上就不會重複的 ID。
歸檔查詢庫 RT 較高
由于歸檔資料庫使用高壓縮比的存儲引擎,這就會導緻歸檔庫查詢 RT 變高,例如生産庫查詢是1ms 的rt,用 tokudb 會變成2ms。
那這個問題,我們就需要從業務上去思考,是否可以接受。
如果你是背景類查詢業務,可以接受高 RT 的查詢,那我們完全可以使用歸檔庫。
那如果你是前台類使用者側查詢,查詢 RT 要低,那就不能接受查詢歸檔庫。
但是從另一方面來講,如果業務上要求查詢 RT 一定要比較低,那這些資料真的适合被歸檔嗎?
歸檔資料缺失,造成業務影響
資料歸檔之後,生産庫就會缺失這部分資料,那如果業務上正好需要使用這些資料,那就會造成業務上異常。
比如說,支付業務中,退款一般需要支援一年以内的訂單。那如果退款的時候,正交易支付的資料正好被歸檔,那就會造成退款的時候找不到對應的支付資料,造成退款失敗。
那這個問題解決辦法有兩種,第一個解決辦法,雙重查詢。如果生産資料庫找不到業務資料,那就去歸檔庫查找。
這個解決辦法适合離線的業務。
第二個解決辦法,設計一個相容方案,提供資料逆向接口,反向将歸檔資料庫的記錄重新還原到生産庫。
那這種解決辦法,隻适合少量因為歸檔資料造成業務異常的業務場景。
總結
資料歸檔可以解決生産資料庫因為資料量過多,進而引發磁盤空間預警,表查詢、變更效率變低等問題。
但是任務方案都存在雙面性,資料歸檔可能引發資料幂等被破壞、歸檔查詢庫 RT 較高、歸檔資料缺失,造成業務影響等問題。
是以我們設計資料歸檔的方案時,需要全面考慮,提前準備預案,解決可能造成的業務問題