背景
概況
公司某項業務使用三個分庫存放該業務的分表。為了保持單表的查詢性能,基於業務場景按照公司維度分表,目前每個庫都有數量達到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
整個遷移過程可以簡化為:
此處不貼詳細的代碼,可以參考官方文檔。
官方數據同步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的日誌需要關注,如果有失敗,任務本身不會停止。你也可以校驗遷移前後表個數、各表數據量是否一致來判斷遷移是否完全成功。
-
重試遷移前,前次遷移創建的表需要手動刪除
-
校驗源表、新表的字段、表名的大小寫是否發生了改變。測試階段確認一次即可。
在下一篇文章中,我會詳細介紹遷移功能模塊的設計和實現。