如何高效地将外部实例迁移到网易云 RDS

社区编辑2018-05-18 15:11

随着网易云在业界知名度的不断提升,有越来越多的新用户开始使用网易云上的各种不同服务,获得了上佳的使用体验。在此背景下,有很多用户开始将已有的存量业务服务迁移到网易云上。
 
业务迁移是个系统工程,牵涉到的模块和组件非常多,在这之中,数据库迁移是必不可少的,也是至关重要的。
 
网易云基础服务 RDS(Relational Database Service,简称 RDS)从 2016 年 4 月开始为用户提供外部 MySQL 实例迁移功能,上线一年以来,极大降低了用户将外部 MySQL 实例迁移到网易云基础服务 RDS 上的技术难度。截止目前,已经累积帮助用户完成了数十例数据库迁移操作,有物理机环境上自建数据库实例的迁移,也有其他云平台上的 RDS 实例的迁移。
 
在之前的文章中,我们已经分享了网易云基础服务 RDS 外部实例迁移功能的实现细节(参阅“[网易云 MySQL 实例迁移的技术实现](https://blog.c.163.com/2017/04/1439/)”),本文为大家带来迁移功能的详细使用方法以及如何提高迁移成功率。
 

迁移过程详解

 

 
如上所示,实例迁移的入口很明显,用户只需要点击“关系型数据库”中的“迁移外部数据库”,即可进入到外部实例迁移页面。
 
“外部实例迁移” ,顾名思义就是要将非网易云基础服务 RDS 的 MySQL 实例(称为源实例)迁移到网易云基础服务 RDS 上来(当然也支持网易云基础服务 RDS 上的实例进行相互迁移,只是这不是主要的应用场景)。为此,首先需要提供外部实例的相关信息,如下:
 

 
用户需要输入源实例的 IP 地址,端口信息,并提供用于进行迁移操作的 MySQL 账号和密码。**在开始迁移前,需要先在源实例上创建足够权限的账号,具体的权限要求可参考网易云基础服务的帮助文档。**对于自建的 MySQL 实例,用户可以使用 MySQL 客户端来新建专用的迁移账号。对于其他的云平台,可在其提供的控制台上新建用于迁移的 MySQL 账号,只需满足帮助文档所述的权限要求即可。
 
迁移前会先连接到源实例,所以,**确保所提供的 IP 地址是公网地址,目前暂不支持迁移用户私网上的 MySQL 实例**。如果用户提供的数据库连接信息无误,账号有足够的权限获取到数据库列表,则会出现如下界面:
 

 
选择您需要迁移的数据库列表,并点击下一步,会提示设置迁移参数。
 

 
这是关键性的一步,对迁移是否能够一次性成功起到决定性作用。
 
首先是迁移类型,不同的迁移类型决定了迁移的结束方式。如果是全量迁移和结构迁移,则迁移会自行结束;若选择增量迁移,则在完成源实例的结构(schema)和全量数据迁移后,还会跟源实例建立复制关系,持续拉取源实例上的增量数据,该复制关系一直保持,直到用户手动选择结束。**增量迁移能够支持迁移在线业务的 MySQL 实例,只需切换一次业务的数据库 IP 地址即可。**
 
其次是导出并发度、导入并发度和负载监控阈值。导出和导入并发度并不影响迁移的成功率,但会极大影响迁移所需的时间,如果希望尽可能快地完成迁移操作同时尽可能减小对源实例上业务的影响,在调高导出和导入并发度的前提下,**合理设置 “负载监控阈值”参数,既可做到快速又将对业务的影响降到能够接受的范围内**。该参数表示从源实例导出数据时,允许 mydumper 工作线程导数据的最大负载,通过 MySQL 状态中的 threads_running 数值来衡量,如果 threads_running 超过所设阈值则数据导出暂停,降到阈值以下后再自动继续。系统默认的监控项为 300,请根据实际情况进行调整。
 
最后是持锁超时时间。这是影响迁移成功率的最重要的参数。在我们之前的分享中已经提过,网易云基础服务 RDS 迁移的内部实现是基于开源 mydumper 和 myloader 进行定制化开发的版本,其部分参数列表如下:
 

 
其中“持锁超时时间”(lock_hold_timeout)就是新增的 mydumper 参数。其意义是为了防止 mydumper 持锁时间太长,导致源实例上的 DML 和 DDL 操作长期阻塞,影响线上业务。
 
确定了迁移参数后,点击“下一步”会进行参数合法性和账号权限的预检查,将问题暴露在开始迁移前,尽可能避免开始导数据后才报错,如下图所示:
 

 
该例子提示用户创建的迁移账号权限不够。用户可以为账号赋予更高权限后,点击“重新检查”来确认是否修复。如果参数设置出错,用户可以点击“上一步”来将参数修改为正确的值。如果账号权限充足,且参数设置正确,则进入到创建新实例的界面,该实例即为迁移后的 RDS 目标实例。如下:
 

 
**用户需根据源实例的规格、存储空间和实例端口,合理设置 RDS 实例的创建参数,请将存储空间设置为大于待迁移的数据库总大小**。默认创建内网 RDS 实例,用户可在完成迁移后,为实例在线开启公网。确认无误后,点击“开始迁移”,系统会新建 RDS 实例,并开始导数据,整个迁移过程会通过“实例迁移进度”页实时更新,入口如下所示:
 

实例详情页上:
 

 
实例列表页上:
 

 
全量和结构迁移进度页如下:
 

 
迁移时,可以通过点击“查看迁移信息”了解本次迁移的数据库列表等信息,避免用户忘记所设置的迁移参数:
 

 
增量迁移进度页如下:
 

 
全量和结构迁移时,将源实例所选的数据库数据导入 RDS 实例后,本次迁移会自动结束。结束迁移后,RDS 实例会先进入“修改中”的状态,2~3 分钟后变为“运行中”。用户可以在迁移结束后将业务请求路由到 RDS 实例上。增量迁移时,需要用户手动点击“结束迁移”来完成本次迁移,这是为了实现在线迁移的目的。在增量迁移过程中,用户可以为 RDS 实例创建业务的 MySQL 账号,如下:
 

 
**在迁移进入增量复制阶段后,若复制延迟逐步缩小到较短时间内,可以暂停线上业务的写入操作,待复制延迟基本为 0 时,将业务的数据库 IP切换为 RDS 实例 IP。确认业务一切正常后,即可结束迁移。**
 
迁移过程中,还可以使用 WebSQL 登陆到 MySQL 上,对 MySQL 进行各种操作,但需要确保不影响正在进行的迁移,比如删除掉迁移中的数据库、表或索引等。
 

 

迁移失败原因及解决

 
在外部实例迁移过程中,有时也会因为各种原因导致迁移失败,需要进行多次重试,虽然这只是少数情况,但为了能够进一步提高迁移的一次性成功率,带来更好的用户体验,下面总结目前主要的失败场景及解决办法。
 
外部实例迁移最容易失败的阶段有两个,分别是权限检查阶段和数据导出阶段。因为这两个阶段的操作对象是源实例,在外部,不在网易云基础服务 RDS 系统内,不可控因素较多,依赖用户的操作行为。
 

1 权限错误

 
其中,权限检查阶段较容易解决,用户甚至可以设置将所有的数据库权限赋予迁移账号,如下所示:
 

 
但需要确保为迁移账号设置了高安全级别的密码。
 

2 数据导出失败

 
而另一个阶段,也就是用 mydumper 进行数据导出阶段,是最容易失败,也最难以解决的。导出阶段失败的场景有:
 
一、在导出源实例数据(包括结构数据和表数据)阶段,用户删除了源实例的迁移账号导致迁移失败,这在增量复制阶段也偶有发生,因为增量复制阶段开始时 RDS 实例需要连上源实例建立 MySQL 复制关系,此时也需要确保迁移账号仍然有效。
 
二、持锁超时,这是网易云基础服务 RDS 实例迁移时最主要的失败原因,该参数默认值为 60s,也就是一分钟,该值在大部分场景下是适用的,但在大表或存在非事务表场景下可能会因为该值设置过小导致迁移因为持锁超时而失败。
  

3 持锁过长原因

 
那么为什么会出现过长的持锁时间呢?下图是 mydumper 在记录级并发备份(导出)的场景下的操作时间序:
 

 
从中可以清晰的看出,mydumper 会持锁创建一致性快照,并将待迁移数据库中的每个表拆分为若干个备份任务,拆分的依据是 rows 参数,表示每个备份任务所负责的记录数。
 
mydumper 主线程完成所有备份任务创建(注意,是创建,而不是执行)。这些备份任务交由多个工作线程执行,如果待迁移的表都是事务表(InnoDB、RocksDB、TokuDB 等),那么任务的执行过程是无锁的。但若存在 MyISAM(非事务)表,则必须在加锁条件下才能得到一致性的数据备份,也就是说在此情况下,需要等待工作线程执行完所有的 MyISAM 表备份任务后,主线程才能解锁。
 
显然,决定持锁时间的因素有:① 是否存在大的 MyISAM 表,若存在,则需要较长的持锁时间;② rows 的设置值,如果 rows 设置过大,会影响数据备份的并发性,延长备份时间,也不利于动态控制导出线程数。如果 rows 设置过小,则需要创建的备份任务非常多,由于创建备份任务是持锁的,也就导致持锁时间过长,所需的具体时间还与源实例所在宿主机的 cpu 能力相关,一般情况下,由于 rows 值导致的持锁时间变长比因非事务表导致的小不止一个数量级。
 
为了让用户尽可能少做决定,将超时的情况降到最低,我们还做了进一步优化:为 mydumper 新增了一个 max-chunks 参数用于限制一个表能创建的最大的备份任务数,最大限度减低超时的概率。
 

 
在迁移时选择合适的超时时间对迁移至关重要,用户应根据源实例的情况,合理设置默认超时时间,尽可能设置为上限值。当然,持锁超时导致迁移失败并不可怕,因为我们提供了重试功能:如果在数据导出阶段失败,那么直接重新导出数据,无需再做迁移的资源分配等迁移准备操作,只需用户根据控制台提示的出错原因,适当调整参数即可;如果是数据导入 RDS 阶段失败,则只需重新导入即可,不需要从导出阶段开始重来。这大大节省了重试带来的时间开销。迁移重试时,根据迁移所处的阶段不同,用户可以对特定的参数进行修改。
 
数据库迁移是整个业务迁移非常关键的一步,虽然我们已经将迁移的难度大大减低,但显然无法确保 100% 的成功率。我们建议在进行业务迁移时,事先联系网易云基础服务客服,协助确定完整而合理的迁移方案。这样,在迁移实施过程中,客服能够处于 ready 状态,随时处理迁移过程中出现的各种情况,确保万无一失。