一.背景
重写项目,将老系统的数据迁移到新系统。涉及合同(2w)、账单(30w)、点位(40w)、调度单(2w)。
合同1:n账单
合同1:1调度单
账单还有无合同账单,减免单。
调度单1:n点位。
点位分为原始点位(eg:电梯)和媒体点位(eg:电梯屏幕,用于做广告),老系统原始点位和媒体点位存放一个表。新系统设计成一个表。
二.需求
在表结构不同的情况下迁移,保证新老完全一致性,老系统新增数据同步。
三.设计
1.全量迁移方案
- 横向迁移
按照业务为维度迁移,一个合同关联对应的账单,调度单,点位进行迁移、再迁移无合同账单。缺点如下
(1)容易遗漏数据
(2)迁移数据更慢 - 竖向迁移
以表维度进行迁移。相比横向迁移
(1)不漏数据
(2)出错相比第一个更容易重试
1.1 因此采用第二种迁移。
问题一:如用自增id,匹配关系对不上,需按表顺序迁移,保存id映射关系。
问题二:如按老系统id,因表结构不同,Id无法匹配,出现冲突。为原系统每个加上表偏移量,如原始点位表+1000,媒体点位+2000,注意流出空余。
问题三:注意新系统新数据自增产生冲突。(问题产生再增量阶段)
- 增量迁移方案
- 改造新老系统,当老系统新增数据时,同步新系统。
缺点:
(1)影响性能
(2)保持一致性困难
(3)代码量改造大
(4)采用mq,一样代码量大 - 定时任务扫描
缺点:
(1)有些表无更新字段,或者更新字段没用上 - 采用监听老系统binlog,解决上面问题。两种设计方案
1.canal
运维成本大,保持HA又需要zk,以及又需要集群部署。
2.mysql-binlog-connector
优点:作为一个依赖jar可以很容易在springboot中使用。
缺点:
(1)没有分布式部署功能(相当于多个对等实例同时监听binlog,重复插入数据)
(2)节点故障,没有保存消费进度。
针对一,采用redis作为分布式协调器,可多机部署实现高可用。原理在创建binlog连接之前,先要获取redis锁,获取锁后会定时刷新锁的过期时间。所有实例会定时重新抢锁。
针对二,mysql库的binlog文件和position会保存在redis里,如果一个实例宕机。新抢到锁的实例在初始化时,会使用上个实例已保存的binlog信息继续获取。
网友评论