分庫分表-首次上線-老數據-數據遷移

爲什麼要分庫分表,分庫分表的實踐請看之前的文章:微服務-分庫分表思路

分庫分表之前我們首先要選出分片字段、然後根據一定的分片算法將數據寫入不同的庫表,查詢數據的時候根據分片字段+分片算法從對應的庫表中拿取數據即可

因此,由單獨進行橫向拆分後需要將老數據按照我們定義的,分片字段和分片算法重新洗數據,那麼我們本節主要講解3中方法:停機數據遷移、新老庫雙寫、寫老庫通過binlog同步新庫

一、上線前停服數據遷移

實踐思路:

  1. 新建線上新庫(按照分片鍵+分片算法新建)
  2. 編寫數據同步程序(查詢老庫,然後按照分片算法遷移到新庫)
  3. 在數據訪問最少的時間段(比如半夜2點)停服務、開始跑我們的同步程序
  4. 數據同步完成後(要進行數據一致性校驗,比如校驗總數)上新代碼,連接新庫

優點:

  1. 數據一致性能得到保障
  2. 簡單,沒什麼技術含量

缺點:

  1. 需要停服務(如果不停服務可能導致已經同步的數據在同步過程中有變更,導致數據不一致)
  2. 數據同步時間較長,出錯率高
  3. 熬夜

題外話:最後一步一定要做數據校驗,如果停服務的話一般校驗數據總條數即可,如果同步過程中出現錯誤,一定要記錄,否則數據矯正略麻煩;如果真的出現數據不一致的情況,提供一直校驗思路:

同樣的查詢條件分表查詢新老庫,分別MD5,然後做對比

二、新老庫雙寫

上一種爲什麼要停服務:就是怕在遷移過程中,有數據修改出現數據不一致的情況,那麼爲了解決數據不一致的情況我們可以在遷移過程中寫的數據,同時寫入新老庫

流程解釋:

  1. 新建線上新庫(按照分片鍵+分片算法新建)
  2. 修改源碼,將之前代碼新增、修改、刪除的地方都修改成同時寫新老庫
    1. 寫入數據庫中間件之前先判斷新庫中是否有此次操作的數據
    2. 新增操作:如果新庫無數據:直接新增,如果有數據:直接丟棄
    3. 修改操作:如果新庫有數據:確保新數據覆蓋舊數據,如果無數據:直接丟棄
    4. 刪除操作:如果新庫有數據:直接刪除,如果無數據:直接丟棄
  3. 啓動後臺數據遷移程序
    1. 查詢老庫,查出數據後通過新庫規則查詢新庫,如果無數據直接寫入,如果有數據比較時間戳,確保新數據覆蓋舊數據,如果是老數據想覆蓋新數據,直接丟棄
  4. 數據遷移完畢後,進行數據校驗
  5. 修改源碼,將之前同時寫新老庫的地方全部改成只寫新庫
  6. 經過一段時間,無異常後下掉老庫和遷移工具

優點:

  1. 對用戶而言無感知,不需要停服務
  2. 有充足的時間檢驗數據的準確性(切新庫之前所有用戶操作都走的老庫)
  3. 不用熬夜

缺點:

  1. 代碼侵入,需要修改兩次源碼,容易漏

總結:上種方法需要很多的判斷,判斷新庫中是否有數據,如果有怎麼處理,如果沒有怎麼處理,牽扯到了一些邏輯,因此我們有沒有一種辦法不用判斷

第二種優化策略

解釋:

  1. 新建線上新庫(按照分片鍵+分片算法新建)
  2. 啓動後臺數據遷移程序,只遷移指定時間以後的歷史數據
  3. 修改源碼,將之前代碼新增、修改、刪除的地方都修改成同時寫老庫可放入消息隊列
  4. 歷史數據遷移完畢校驗通過後,遷移程序開始監聽消息隊列,將擠壓消息寫入到新庫
  5. 當新老庫數據校驗通過,切到讀寫新庫

總體思路:先遷移老數據,然後消費新數據,不需要各種邏輯判斷

當然缺點還是沒有避免,還是要修改源碼,有沒有不修改源碼的呢,,,

三、讀寫老庫,通過老庫binlog同步新庫

解釋:

  1. 將老庫binlog開啓row level模式下
  2. 新建線上新庫(按照分片鍵+分片算法新建)
  3. 啓動後臺數據遷移程序,只遷移指定時間以後的歷史數據
  4. 歷史數據遷移完畢校驗通過後,遷移程序開始監聽binlog的增刪改事件,將消息寫入到新庫
  5. 當新老庫數據校驗通過,切到讀寫新庫

題外話:監聽binlog增刪改事件可以用阿里的canal

 

公衆號主要記錄各種源碼、面試題、微服務技術棧,幫忙關注一波,非常感謝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章