整理常見的千萬級數據分表的遷移方案

    在互聯網業務中我們會遇到千萬級別數據量的表需要拆分成多表存儲,或者底層的數據存儲介質的變更等原因都需要做數據的遷移,今天我們來聊聊數據的遷移方案。

1、數據的遷移策略

    假設現在又一張千萬級別的訂單明細表,我們需要拆分成多張子表存儲,那麼我們按照什麼規則來將訂單的明細放入子表中呢?

(1)哈希取模方式

    訂單明細中可以選擇訂單 id 作爲 key 進行哈希取模來確定數據應該存儲在哪個子表中,如下所示:

    在具體選擇哪個字段爲 key 的時候,我們能需要根據實際的業務中哪個字段的查詢最爲頻繁,目的是儘量減少跨表查詢。常見的 key 可以選擇如訂單 id、用戶 id 等等字段,採用這些字段作爲分表的 key,可以避免跨表查詢的問題。

(2)基於範圍分表

    首先需要確定一個合適的範圍來進行數據遷移,常見的方案又基於時間範圍或基於 id 範圍進行分表遷移。

    基於時間分表遷移是根據時間範圍(如同一年的數據放在一個表)將數據劃分出來,如下所示:

    基於 id 範圍進行數據遷移的方案是維護一張 id 訪問表,然後將指定的 id 範圍放入某張表中,如下所示:

    具體要用哪種遷移數據的策略要根據具體的業務場景,主要是基於性能、可維護性等方面考慮,最後再確定遷移的策略。

2、數據的遷移方案

2.1 停機遷移

    停機遷移是一種直接且粗暴的方法,停機遷移會影響用戶的正常訪問,所以通常會提前給用戶一個友好的通知,如下是停機遷移的圖:

    爲了降低遷移過程中帶來的影響,一般都是選在凌晨進行數據的遷移,這樣儘量將風險降到最小。許多遊戲公司的服務器升級,遊戲分區與合區,都可能會採用類似的方案。

2.2 雙寫策略

    雙寫策略是繼續向老表寫入數據,同時再根據分表策略把數據寫入到新的分表中,並記錄開始同步新表數據的時間,如下圖所示:

    爲了保證數據雙寫一致性,我們需要使用定時任務對新舊錶中的數據進行對比,確保數據寫入無錯誤。經過一段時間的雙寫之後,如果沒有任何的問題,基於最早同步的時間點把原始表之前的數據遷移到新表。

2.3 MQ+Redis 實現數據的遷移

    使用 MQ+Redis 做數據遷移是一種比較平滑遷移方案,方案的流程圖如下所示:

(1)制定遷移方案

    對於千萬級別的數據量遷移,首先根據 id 範圍劃分的策略,如每一萬個數據劃分成一組,然後對遷移的原始表和目標都使用 Redis 的 bitmap 記錄每條數據的遷移情況,數據分成多少組,就使用多個 Redis 的 key,key 的命名含義如下:

redis_source_key:表示遷移表中 Redis 的 key

source_tb_s1e10:表示遷移表中開始的 id 從 1 開始,結束的 id 是 10000,這樣就表示 id 在 1-10000 範圍的數據。

redis_target_key:表示目標表的 Redis 的 key

target_tb_s1e10:表示目標表中開始的 id 從 1 開始,結束的 id 是 10000,這樣就表示 id 在 1-10000 範圍的數據在目標表中的保存情況(主要是記錄是否保存到目標表)。

    同時在 Redis 中也需要記錄每個分組(如 1-10000)中本次遷移的開始時間,使用 key 單獨記錄(如 source_tb_s1e10_startTime);記錄每個分組中遷移的狀態(如遷移完成、正在遷移),使用 key 單獨記錄(如 source_tb_s1e10_status)。

    記錄分組開始的時間和分組的遷移狀態的目的是爲了定時任務做數據的補償。

(2)執行遷移方案

    執行遷移方案就是將源表中的數據分組後使用 MQ 的方式發送到消息隊列中,然後在 Redis 的 bitmap 中記錄每條數據的遷移情況,如下所示:

對應的 bit 位上爲 1 就表示數據已經發送 MQ 中等待消費。

    在消費端來消費隊列中的消息,然後按照遷移數據的策略將數據落目標表中保存下來,保存成功之後在 Redis 的目標 key 中並記錄消費情況,如下所示:

對應的 bit 位上爲 1 就表示數據已經消費成功。

(3)數據補償

    爲了保存數據遷移中不被遺漏,我們可以採用定時做補償機制,原理是通過掃描 Redis 中分組遷移狀態是 key(如 source_tb_s1e10_status)是成功狀態,如下所示:

    然後把遷移狀態是成功爲 key 的生產端和消費端的 bitmap 做異或處理,將異或結果爲 1 的數據拿出來,如下所示:

    通過比對發現 bit 位的 3 和 4 位置上數據不一致(也就是生產端生成成功,但是消費端消費失敗),那麼根據這個分組的開始遷移的時間與當前的時間做比對,如過大於設置的時間(如 1 小時),那麼我們就需要手動的補償數據。

總結:

(1)數據的遷移策略有哈希取模、基於時間、基於 id 範圍等常見的方案。

(2)常見的數據遷移的方案有停機遷移、雙寫遷移以及 MQ+Redis 方案遷移。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Xbucnsm6b9eanNMLl7aVuA