博客 / 詳情

返回

DTS按業務場景批量遷移阿里雲MySQL庫實戰(上):技術選型和API對接

背景

概況

公司某項業務使用三個分庫存放該業務的分表。為了保持單表的查詢性能,基於業務場景按照公司維度分表,目前每個庫都有數量達到10W級的分表。過多的表已經影響了日常的運維,元數據相關的操作如搜索表名等在線操作速度極慢。隨着業務的發展,分表數量還會增加。

現狀

  • Springboot+阿里雲RDS-MySQL8

  • 分庫分表中間件:MybatisPlus+ShardingSphereDataSource

  • 分庫方式,創建公司時使用公司id%3計算schemaId,創建完成後不變,各分表均有這一列

  • 分表方式,有三種,對應三種分表後綴:

    • 公司維度,table_companyId

    • 公司+年份維度,table_company_year

    • 業務id維度,table_bizId,bizId在前置業務處理時生成,一般一個公司一年只有一個bizId

  • 每個公司大概有15~50張分表,它們的結構不完全相同,但是對於前綴相同的表結構是相同的,比如table1_company_2024和table1_company_2025,或者table2_655和table2_656。

  • 不同的分表可能會做join查詢

預期

申請更多的分庫,將現有的表遷移至新的分庫中,降低原有庫的表數量。

遷移方案選型

純Java實現

如果業務簡單、數據量不多,只需要做一部分表的遷移,使用jdbc逐表複製創建對應的新表、複製數據,是完全夠用的。但是在當前的業務場景下:

  • 至少有20種不同結構的分表,針對每種結構寫對應的遷移代碼,工作量不小

  • 難以維護:當分表結構發生調整、增加新的結構的分表時,遷移代碼也需要修改,也就是説,其他項目引入的變更,還要來修改遷移的代碼

  • 開發者要自己控制遷移過程,比如大數據量的分片遷移、遷移過程中的失敗重試等

阿里雲DTS

既然這部分業務跑在阿里雲RDS上,使用現成的DTS中間件是更好的選擇。雖然有一定的學習成本,但是它有兩個明顯優勢:

  • 阿里雲RDS內部通過DTS做數據遷移是不收費的:計費概述

  • 數據遷移,只要指定好源庫、目標庫、待遷移的表,DTS會自動創建新表結構和數據同步,並確保遷移高可用與數據準確性

在做了簡單的調研(包括寫一個簡單的DTS數據遷移demo)、確認DTS可以滿足遷庫表的需求後,我選擇了DTS的,通過接入DTS API完成庫表遷移。

確認遷移場景滿足DTS限制

源庫的注意事項及限制

目標庫的注意事項及限制

DTS實例的注意事項及限制

(以上三篇文檔實際上是同一篇文檔不同小結)

DTS準備

如果你也要通過demo的形式做前期驗證,也需要先做準備工作。由於我使用的不是阿里雲主賬號而是RAM賬號,這部分準備工作只知道個大概,你可以參考官方文檔進行配置。

  • 購買DTS產品,由於是後付費的,並且我的遷移場景不會產生實際的付費項,費用實際為0。

  • 授予DTS訪問雲資源的權限

  • 創建DTS專用的獨立RAM賬號創建RAM用户,此處使用【使用永久AccessKey訪問】,並賦予其讀寫權限通過系統策略授權子賬號管理DTS

  • 將DTS服務器添加到數據庫IP白名單(對於RDS Mysql不需要)

DTS API對接

SDK安裝

我使用的是同步版JavaSDK,同步版和異步版在文檔上不區分,應該是通用的。文檔:數據傳輸_SDK中心-阿里雲OpenAPI開發者門户

使用API

整個遷移過程可以簡化為:

image

此處不貼詳細的代碼,可以參考官方文檔。

官方數據同步demo

DTS SDK新版API同步任務創建示例_數據傳輸_示例中心-阿里雲OpenAPI開發者門户

本例實例type是"SYNC",代表數據同步,我使用的是"MIGRATION",代表數據遷移。除了這個參數,其他參數設置基本一樣。

創建實例

CreateDtsInstance_數據傳輸_API文檔-阿里雲OpenAPI開發者門户

配置任務

ConfigureDtsJob_數據傳輸_API文檔-阿里雲OpenAPI開發者門户

一個實例只能配置一個任務。

TableConfig配置

想要只遷移指定的庫表,需要配置TableConfig參數,文檔見遷移、同步或訂閲對象説明。本次典型的單個DTS數據遷移任務的場景:

  • 單個庫到單個庫

  • 一次性多張表(建議不超過1000)

  • 配置字符串長度不超過1MB

{
    "待遷移的源庫1的名稱": {
        "name": "遷移、同步或訂閲的庫1在目標實例中的名稱",
        "all": false(表示遷移、同步或訂閲對象為非整庫),
        "Table": {
            "待遷移的表A的名稱": {
                "name": "遷移、同步或訂閲的表A在目標實例中的名稱",
                "all": true(表示遷移、同步或訂閲對象為整表)
             }
        }
    }
}

Reserve配置

DTS可以通過ETL設置遷移後的表中某些列的值,即將舊的schemaId改成新庫對應的值,在任務配置的Reserve參數中增加對應配置如下:

{
        "targetTableMode": "0",
        "etlOperatorCtl": "Y",
        "etlOperatorSetting": "e_set(schemaId, '%d', schema_id,'%d')"
}

ETL用法:在DTS遷移或同步任務中配置ETL

Reserve參數用法:Reserve參數説明

先購買後配置時autoStartModulesAfterConfig默認auto, 配置完任務會立即啓動。

暫停DTS任務

SuspendDtsJob_數據傳輸_API文檔-阿里雲OpenAPI開發者門户

結束DTS任務

StopDtsJob_數據傳輸_API文檔-阿里雲OpenAPI開發者門户

查詢單個DTS任務詳情

DescribeDtsJobDetail_數據傳輸_API文檔-阿里雲OpenAPI開發者門户

補充工作

除了通過DTS遷移表本身外,還有一些工作需要關注:

  • 歸檔是阿里雲RDS的一大功能。如果源表是歸檔的,遷移後的目標表也應該是歸檔的。如何判定表是否歸檔及變更歸檔狀態參考數據歸檔功能

  • DTS的日誌需要關注,如果有失敗,任務本身不會停止。你也可以校驗遷移前後表個數、各表數據量是否一致來判斷遷移是否完全成功。

  • 重試遷移前,前次遷移創建的表需要手動刪除

  • 校驗源表、新表的字段、表名的大小寫是否發生了改變。測試階段確認一次即可。

在下一篇文章中,我會詳細介紹遷移功能模塊的設計和實現。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.