分库分表详解 中- 数据迁移

250 阅读5分钟

分库分表后我们需要将原有的数据迁移到新的数据和表中 一般会有停机迁移和不停机迁移两种方案,下面给大家讲解一下, 这两种方案分别怎么做,和需要关注的点

停机迁移

优点:

简单 停机迁移因为系统停机 所以数据不会新增只需要将存量数据迁移到新的库表中即可

缺点:

需要停机 数据多的话可能停机时间较长 而且如果迁移失败可能需要再次迁移

不停机迁移

优点:

系统不需要停机 可以无感迁移

缺点:

方案较复杂需要关注

  • 增量数据迁移
  • 存量 数据迁移
  • 数据迁移过程中的数据校验
  • 老库 新库切换方案
  • 灰度方案

不停机迁移方案

核心流程

双读双写

双读双写流程:写旧读旧 -> 双写读旧 -> 双写双读(核对) -> 双写读新 -> 写新读新

(1)代码梳理: 对需要迁移的读写接口进行整理 并改造编写对应的代理类;

(3)双写:控制往老库写数据,还是往新库写数据。在灰度期间,既要写老库又要写新库,新库写失败,不能影响老库数据的写入,不能影响服务。双写不一致数据需要有补偿兜底,如增量迁移兜底还有双读校验等。

(4)双读:双读的目的是在实时数据核对不一致时,控制返回老库的结果,还是返回新库的结果。在代理层对所有的读操作进行灰度控制(如果没有灰度字段,需要改造代码)开关控制是否需要读新库、老库数据做对比,如果对比校验两边数据一致,则返回新库数据,否则返回老库数据,同时打印不一致的内容,补偿数据,排查不一致的原因。

数据迁移

(1)存量数据迁移:将老库中已经存在的数据批量迁移到新库,在进行存量数据迁移前。需要注意一下数据迁移完成的时间,适当使用多线程同步,注意控制qps,也可以加上开关保证有问题时迁移任务能够立即停止(停止时打印当前迁移的位置,下次可以从暂停位置继续迁移),以免对线上服务造成影响。

(2)开启双写:存量数据迁移完成之后,开启双写,同时写老库与新库。存量数据迁移过程中,数据可能会更新,因此还需要进行增量迁移。

(3)增量数据迁移:将老库更新时间大于存量数据迁移开始时间的数据,再迁移到新库一遍

可能出现的问题

  • 老库执行insert操作后

新库执行insert操作,操作一定能成功,因为新库的数据是老库的子集,老库既然可以插入成功,那么新库也可以插入成功,此时老库新库都插入了数据;

  • 老库执行delete操作后

根据删除的数据所处的区间,分为两种情况:

(1):假设delete的数据属于[start, current]范围,即已经写入了新库,则老库新库都删除了该条数据,数 据一致性没有被破坏;

(2):假设delete的数据属于[current, latest]范围,即还未写入新库,则老库中删除操作的affect rows(影响的行数)为1,新库中删除操作的affect rows为0。但是数据迁移任务在后续数据迁移中,因为这条"未来的"数据已经从旧库删除,因此并不会将这条旧库中被删除的数据迁移到新库中,所以数据一致性仍没有被破坏;

  • 老库执行update操作后

根据更新的数据所处的区间,分为两种情况:

(1):假设update的数据属于[start, current]范围,即已经写入了新库,则老库新库都更新了该条数据,数据一致性没有被破坏;

(2):假设update的数据属于[current, latest]范围,即还未写入新库,数据迁移任务在后续迁移中,这条数据也会被正确迁移。

特殊情况

数据迁移时刚好从老库将数据取出,准备迁移插入到新库;同时旧库发生了update或delete操作;新库的数据和旧库的数据就存在了差异。

数据校验与订正

存量、增量数据迁移完成后,由于删除、并发更新冲突等特殊情况,以及迁移的代码可能存在问题。因此数据校验与订正是必要的,校验老库和新库的所有字段数据是否一致。校验方式可以通过:

(1)实时内存双读校验

(2)接口抽样/全量数据校验

(3)离线同步数据,通过脚本校验

校验后,可能会发现各种数据不一致的问题,需要修正迁移逻辑,将不一致的老库和新库进行数据订正,保证一致性。

切流

(1)当数据校验完成后,可以进行灰度切流;

(2)需要制定好一个切流计划,在什么时间段,放出多少的流量,并且切流的时候要选择流量比较少的时候进行切流,每一次切流都需要对日志做详细的观察,出现问题尽早修复。流量的放出过程是一个由慢到快的过程,比如最开始是以1%的量去不断叠加的,到后面的时候以10%,20%的量去快速放量。因为如果出现问题的话往往在小流量的时候就会发现,如果小流量没有问题那么后续就可以快速放量

完成迁移

切流和后处理完成,然后观察各个业务后续工单反馈情况和各个系统预警与日志;双写关闭,只写新库,观察新库性能,确保新库的稳定性。