如何设计并实现阿里云DTS批量迁移RDS MySQL表的迁移管理平台?
摘要:本文是 阿里云DTS按业务场景批量迁移RDS MySQL表实战(上):技术选型和API对接 的后续,使用设计模式中的状态模式,完成业务系统中的迁移模块。DTS的对接方式可参考前文。 迁移管理平台设计与实现 完成DTS API对接后,就需要考
本文是 阿里云DTS按业务场景批量迁移RDS MySQL表实战(上):技术选型和API对接 的后续,使用设计模式中的状态模式,完成业务系统中的迁移模块。DTS的对接方式可参考前文。
迁移管理平台设计与实现
完成DTS API对接后,就需要考虑如何将DTS和业务系统有机结合实现整套的迁移流程。
出于信息安全角度的考虑,本文删除了大量涉及实际业务的实现代码。
业务约束
从业务出发,最好的体验肯定是用户无感的,即迁移完成后,确认新旧表数据一致,直接切换到新表查询。
如果迁移期间,用户对旧表进行了写入,新表可能会少数据,不能贸然切换,要做数据的对比。如果用户一直在写入,就要一直反复的对比、确认,有增量数据就要删除新表重新迁移,流程复杂。
和业务方沟通,得知对方可以接受:禁止写入正在迁移的公司的表,向用户报错,等迁移完成后再恢复使用。
这样流程就简单多了,开始迁移时,将旧表重命名增加特殊的后缀,就能防止用户操作,并确保旧表数据不发生变更。
技术校验
如何判断一个公司是否迁移成功?最严谨的方式是逐表逐行数据对比,但是在使用DTS的情况下并无必要。我采取的比较策略是,在迁移前后:
源表目标表数量相同
对应表数据量相同、数据最后更新时间(如有此列)相同
只要满足以上要求,就认为数据是一致的。可以通过SELECT COUNT(*), MAX(updateTime) FROM table_name一次性获取。
迁移状态机
经过分析和简化,迁移状态机如下:
可以发现,每个状态都可以进行“推进”和“回滚”两个动作,很适合使用状态模式来实现。状态模式的实现先放一放,看看几个基本数据结构:
迁移任务
@Data
public class TableMigrateTask {
// 主键
private Long id;
// 公司id
private Long companyId;
// 原始分库位
private Long oldSchemaId;
// 新分库位
private Long newSchemaId;
// 任务状态
private Integer state;
// DTS任务状态,和阿里云定义一致
private String dtsStatus;
// DTS任务已删除(释放)
private Boolean dtsDeleted;
// DTS实例id
private String dtsInstanceId;
// DTS任务id
private String dtsJobId;
// 失败原因
private String failedReason;
// 状态跳转时的信息,辅助排查问题
private String transitInfo;
// 迁移前表数据统计,json格式,表名、数据量、最后更新时间
private String tableStatisticsSrc;
// 迁移表结果统计,json格式kv结构,表名-数据量
private String tableStatisticsDest;
}
迁移上下文
迁移状态机实际处理的对象,封装了一些服务,可以视为领域对象(充血模型)。
