迁移过程需要满足的要求
- 在线进行迁移,即期间会有数据的写入;
- 迁移前后数据一致性;
- 故障预防,迁移过程可以进行回滚,且不会对系统可用性造成影响。需要注意的是,通过同步 binlog 的方式迁移数据,在同步完成后再修改代码,将主库修改为新的数据库,这样就不满足可回滚的要求,一旦迁移后发现问题,由于已经有增量的数据写入了新库而没有写入旧库,不可能再将数据库改成旧库。
数据库迁移方案
“双写”方案
双写方案的流程
- 新库作为从库来同步数据。可以使用数据库自身的同步方式,也可以选择基于 Binlog 进行同步。后者的好处是可以从单表迁移为多库多表。
- 数据写入时同时写入两个数据库。出于性能,新库采用异步写入 + 写入失败的数据记录在日志。开始同步写入之前,需要在流量低峰期关闭主从同步关系。
- 抽样校验数据。由于数据量较大,全量不现实,可以抽取部分数据进行一致性校验。
- 最好采用灰度的方式来切换,比如开始切换 10% 的流量,如果没有问题再切换到 50% 的流量,最后再切换到 100%。
- 双写的存在,切换过程中出现问题可以再将读写流量切换回旧库。
- 观察几天系统无问题后,就可以将数据库的双写改造成只写新库。
数据从机房迁移到云端
如果是将数据从自建机房迁移到云上,你也可以使用这个方案,只是你需要考虑的一个重要的因素是:自建机房到云上的专线的带宽和延迟,你需要尽量减少跨专线的读操作,所以在切换读流量的时候你需要保证自建机房的应用服务器读取本机房的数据库,云上的应用服务器读取云上的数据库。这样在完成迁移之前,只要将自建机房的应用服务器停掉并且将写入流量都切到新库就可以了。

优点和缺点
- 优点 1: 迁移方案比较通用,可以迁移 MySQL、Redis、MQ 数据。
- 优点 2: 迁移的过程可以随时回滚,将迁移的风险降到了最低。
- 缺点: 时间周期比较长,应用有改造的成本。
级联同步方案
级联同步简介
方案也比较简单,适合数据从自建机房向云上迁移的场景。因为迁移上云最担心云上的环境和自建机房的环境不一致,会导致数据库在云上运行时因为参数配置或者硬件环境不同出现问题。
级联方案同步流程
- 在自建机房准备一个备库,在云上环境上准备一个新库,
- 先将新库配置为旧库的从库,用作数据同步;
- 再将一个备库配置为新库的从库,用作数据的备份;
- 等到三个库的写入一致后,将数据库的读流量切换到新库;
- 然后暂停应用的写入,将业务的写入流量切换到新库(由于这里需要暂停应用的写入,所以需要安排在业务的低峰期)。

级联同步的回滚方案
先将读流量切换到备库再暂停应用的写入,将写流量切换到备库,这样所有的流量都切换到了备库,也就是又回到了自建机房的环境,就可以认为已经回滚了。
优点和缺点
- 优点:实施简单,业务上基本没有改造成本
- 缺点:存在短暂的停止写入
数据迁移时如何预热缓存
Redis 的数据迁移可以使用双写的方案或者级联同步的方案。
使用副本组预热缓存
在“缓存的使用姿势(二):缓存如何做到高可用?”中,我曾经提到为了保证缓存的可用性,我们可以部署多个副本组来尽量将请求阻挡在数据库层之上。
数据的写入流程是写入 Master、Slave 和所有的副本组,而在读取数据的时候,会先读副本组的数据,如果读取不到再到 Master 和 Slave 里面加载数据,再写入到副本组中。那么,我们就可以在云上部署一个副本组,这样,云上的应用服务器读取云上的副本组,如果副本组没有查询到数据,就可以从自建机房部署的主从缓存上加载数据,回种到云上的副本组上。

当云上部署的副本组足够热之后,也就是缓存的命中率达到至少 90%,就可以将云机房上的缓存服务器的主从都指向这个副本组,这时迁移也就完成了。
这种方式足够简单,不过有一个致命的问题是:如果云上的请求穿透云上的副本组,到达自建机房的主从缓存时,这个过程是需要跨越专线的。
这不仅会占用较多专线的带宽,同时专线的延迟相比于缓存的读取时间是比较大的,即使是本地的不同机房之间的延迟也会达到 2ms ~ 3ms,那么一次前端请求可能会访问十几次甚至几十次的缓存,一次请求就会平白增加几十毫秒甚至过百毫秒的延迟,会极大地影响接口的响应时间,因此在实际项目中我们很少使用这种方案。
但是这种方案给了我们思路,让我们可以通过方案的设计在系统运行中自动完成缓存的预热,所以我们对副本组的方案做了一些改造,以尽量减少对专线带宽的占用。
改造副本组方案预热缓存
改造后的方案对读写缓存的方式进行改造,步骤是这样的:
- 在云上部署多组 mc 的副本组,自建机房在接收到写入请求时,会优先写入自建机房的缓存节点,异步写入云上部署的 mc 节点;
- 在处理自建机房的读请求时,会指定一定的流量(比如 10%)优先走云上的缓存节点,这样虽然也会走专线穿透回自建机房的缓存节点,但是流量是可控的;
- 当云上缓存节点的命中率达到 90%以上时,就可以在云上部署应用服务器,让云上的应用服务器完全走云上的缓存节点就可以了。
使用了这种方式,我们可以实现缓存数据的迁移,又可以尽量控制专线的带宽和请求的延迟情况,你也可以直接在项目中使用。