关注公众号【1024个为什么】,及时接收最新推送文章!
服务迁移是个大的概念,可以细分到很多种服务, 数据库服务迁移、redis 服务迁移、RPC 服务迁移 等等。
本次就聊一下我经历过的数据库服务迁移。
场景一:连接信息都不变,业务服务不重启
操作步骤
(一)先开启 DTS 同步全量、增量数据
(二)数据同步一致后,切换域名指向新库
此时连接池里新创建的连接(c4、c5、c6)会和新库建立 TCP 连接,连接池里老的连接(c1、c2、c3)对应的 TCP 连接还是在老库上,此时新老库都会有数据进来。
(三)新库的连接、数据 验证通过后,看老库里是否还有连接,有的话需要 KILL 掉
如果不及时 KILL 掉老库的连接,新老库同时写数据,持续时间越长,数据不一致的风险越高。
(四)KILL 掉老库连接后,由于连接断开,连接池里老库的连接失效,会触发连接池新建连接,此时新建的连接(c7、c8、c9)就会和新库建立 TCP 连接
(五)确定老库没有连接,数据验证通过,业务服务也正常,此时就可以关闭 DTS 同步
场景二:连接信息变了,业务服务需改动上线
为了使业务无感知,可以采用分批切换的方案。(也可以在业务服务中加个新老库切换的开关)
操作步骤
(一)先开启 DTS 同步全量、增量数据,停掉一部分服务
(二)上线采用新连接信息的代码,部署在刚才停服务的节点上,新上线的节点流量就会打到新库上
(三)观察数据、服务都正常后,操作剩余节点
(四)观察数据、服务都正常后,关闭 DTS 同步
场景三:对数据一致性要求极高,需要停服务迁数据库
这种场景可以根据自己的业务,确定停服务的方案,有条件的话全停是最稳妥的。
如果不想让客户什么都不能用,又要保证数据的一致性,可以把【写操作】都停掉,【读操作】可以正常使用,这当然需要评估到所有写操作场景,再进行开发适配。
具体操作步骤和场景二类似,就不再画图了。
回滚方案:
回滚方案基本就是迁移操作的逆向,需要记录两次操作的时间段,验证两个时间段的数据是否一致。
注意点:
(1)DB 一般都有 IP 白名单的配置,新库的白名单里要加上业务服务的 IP。
(2)DB 系统配置,有些服务可能根据自身的流量修改了系统配置,要保证新老库配置信息一致。
(3)数据库连接池,前面步骤里已经介绍了,这里补充一点。
KILL 掉连接的时候会不会丢数据?
不会,这个连接对应的事务如果还未提交,这个事务里的数据会被回滚,业务要能正确处理 MySQL 异常,也就是闪断问题。
(4)主键 ID,如果主键 ID 是自增 ID ,新库表里的自增 ID 需要人工设置新起始值,根据自己的业务量和 步骤2、3 操作的耗时,评估出一个合理的值,加在原有 lastId 上就可以,我们一般加 10000 就够了。
修改自增 ID 起始值,必须在步骤 2 之前,如果是回滚,则需要在流量切回老库前修改。
如果不修改自增ID,在步骤 3 之前新老库双写,DTS 同步时会产生主键冲突,数据默认会被覆盖。
(5)定时任务、数仓,这种一般不用连接池,所以通过 DB 连接反查客户端就查不到,这种就需要直接从代码里搜,如果有,也需要加上 IP 白名单。
确定流量低峰的时候也要考虑这一点,如果漏掉了,碰巧迁库的时候定时任务执行了,那就悲剧了。
(6)Canal,如果有使用 Canal 同步数据的,还需要修改 Canal 配置信息。
最后这 2 个注意点,一般上线后很少再改动,很容易被忽略,而一旦出问题,影响却很大,所以要格外注意。
扯两句
所有的服务迁移都要在流量低峰时间段
服务迁移本身并不难,难的是方方面面考虑全
原创不易,多多关注,一键三连,感谢支持!