進來偷學一招,資料歸檔二三事兒

樓下小黑哥發表於2021-07-10

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 較高、歸檔資料缺失,造成業務影響等問題。

所以我們設計資料歸檔的方案時,需要全面考慮,提前準備預案,解決可能造成的業務問題

相關文章