進來偷學一招,數據歸檔二三事兒
Hello,大家好,我是樓下小黑哥~
隨著業務的快速增長,業務體量變得越來越大,這個過程我們會碰到各種問題,倒逼著我們進行技術升級。
那今天我們來聊下,這個過程將會碰到關於數據的問題。
數據增長帶來的煩惱
業務快速增長,業務表數據記錄不斷在增加,這就會帶來兩個問題。
第一,資料庫數據最終將會保存在本地磁碟中,數據記錄越多,磁碟佔用空間就會越多,對應剩餘可用空間就會越少。
剩餘空間到達一定的閾值之後,將會引發磁碟空間的持續報警,消耗寶貴的資料庫生產伺服器的資源。
第二,業務表記錄越多,表查詢的效率就會相應變低,另外表變更也會變的很麻煩。
那解決這個問題,解決辦法有很多,那 今天介紹其中一種方式,數據歸檔。
數據歸檔
數據歸檔的解決思路非常簡單,就是將生產庫的數據轉移到擁有相同表結構的資料庫中,通過減少生產庫記錄數量,從而提高數據查詢等操作的效率。
數據歸檔的流程如圖所示:
數據歸檔分為三個流程
- 創建一個新的資料庫-歸檔庫,然後在歸檔庫創建與生產庫相同的表
- 不斷查詢生產庫數據記錄,同步複製到歸檔庫
- 生產庫刪除已經複製的數據記錄
雖然數據數據歸檔流程非常簡單,但是設計數據歸檔的方案,我們必須想清楚以下幾個問題:
- 歸檔前:那些數據可以歸檔?歸檔庫如何選型?
- 歸檔中:數據歸檔的執行方案
- 歸檔後:數據歸檔帶來問題預案
歸檔之前
首先我們需要思考第一個問題,那些數據可以歸檔?
表數據量很大,並且存在很明顯的冷熱數據,冷數據幾乎很少訪問。
一個非常典型的例子,訂單數據。我們通常訪問最近的歷史訂單,而一年前的歷史訂單查看就會很少。
又比如優惠券數據,還未過期的優惠券,可能需要被查詢使用。而一年前過期的,或者說已經被使用的優惠券,就會被很少訪問。
所以,設計數據歸檔的之前,我們需要思考,我們歸檔的數據是否適合被歸檔。
第二,我們需要思考歸檔資料庫的選型。
數據歸檔主要目的是為了節約寶貴的生產伺服器存儲,數據需要經過壓縮後才會存到資料庫。
所以,歸檔庫需要選擇那些支援高壓縮比的存儲引擎。
我們目前歸檔庫選型使用 TokuDB 引擎的 MySQL資料庫,壓縮比大約為6:1。
歸檔之中
上面流程我們看到,數據歸檔無非就是查詢數據,插入數據,然後刪除數據。
那我們可以基於這個流程開發一個通用的歸檔腳本。
Google 搜索了一圈,在 Github 上找到了一個歸檔小工具,基本上實現了數據歸檔的自動運轉,統一的歸檔任務調度管理、自動監控和預警、自動生成報表。在一定程度上節約了生產力,提高了運維效率。
github地址://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 較高、歸檔數據缺失,造成業務影響等問題。
所以我們設計數據歸檔的方案時,需要全面考慮,提前準備預案,解決可能造成的業務問題