当前位置:网站首页>线上数据库迁移的几种方法
线上数据库迁移的几种方法
2022-07-04 18:00:00 【Koikoi123】
互联网系统,经常会有数据迁移的需求。系统从机房迁移到云平台,从一个云平台迁移到另一个云平台,系统重构后表结构发生了变化,分库分表,更换数据库选型等等,很多场景都需要迁移数据。
在互联网行业,很多系统的访问量很高,即便在凌晨两三点也有一定的访问量。由于系统数据迁移,导致服务暂停几分钟,是很难被业务方接受的!本文我们就来聊一下,在用户无感知的前提下,如何设计不停机数据迁移方案!
数据迁移过程我们要注意哪些关键点呢?第一,保证迁移后数据准确不丢失,即每条记录准确而且不丢失记录;第二,不影响用户体验(尤其是访问量高的C端业务需要不停机平滑迁移);第三,保证迁移后的性能和稳定性。
传统技术方案
传统方案一般由DBA来做,DBA先停止数据库的使用,然后书写迁徙脚本把数据导出到一个中间文件。然后再书写导入脚本,导入目标库。
传统方案的缺点
- 数据库会停止服务几小时甚至几天,应用程序无法使用,在一些行业应用中基本不可接受。
- 不能满足异构数据的迁徙,如果oralce或sqlservcer和mysql的数据结构不一样,有着比较复杂的映射关系,需要做数据转换,不能满足迁徙。
挂从库
在主库上建一个从库。从库数据同步完成后,将从库升级成主库(新库),再将流量切到新库。这种方式适合数据结构不变,而且空闲时间段流量很低,允许停机迁移的场景。一般发生在平台迁移的场景,如从机房迁移到云平台,从一个云平台迁移到另一个云平台。大部分中小型互联网系统,空闲时段访问量很低。在空闲时段,几分钟的停机时间,对用户影响很小,业务方是可以接受的。所以我们可以采用停机迁移的方案。步骤如下:
1,新建从库(新数据库),数据开始从主库向从库同步。
2,数据同步完成后,找一个空闲时间段。为了保证主从数据库数据一致,需要先停掉服务,然后再把从库升级为主库。如果访问数据库用的是域名,直接解析域名到新数据库(从库升级成的主库),如果访问数据库用的是IP,将IP改成新数据库IP。
3,最后启动服务,整个迁移过程完成。
这种迁移方案的优势是迁移成本低,迁移周期短。缺点是,切换数据库过程需要停止服务。
双写
老库和新库同时写入,然后将老数据批量迁移到新库,最后流量切换到新库并关闭老库读写。
这种方式适合数据结构发生变化,不允许停机迁移的场景。
一般发生在系统重构时,数据结构会发生变化,如表结构改变或者分库分表等场景。有些大型互联网系统,平常并发量很高,即便是空闲时段也有相当的访问量。几分钟的停机时间,对用户也会有明显的影响,甚至导致一定的用户流失,这对业务方来说是无法接受的。所以我们需要考虑一种用户无感知的不停机迁移方案。以笔者之前经历的用户系统重构为例,聊一下具体方案。当时的场景是这样的,用户表记录数达到3000万时,系统性能和可维护性变差,于是我们将用户中心从单体工程中拆分出来并做了重构,重新设计了表结构,而且业务方要求不停机上线!下面是我们当时的方案,步骤如下:
- 代码准备。在服务层对用户表进行增删改的地方,要同时操作新库和老库,需要修改相应的代码(同时写新库和老库)。准备迁移程序脚本,用于做老数据迁移。准备校验程序脚本,用于校验新库和老库的数据是否一致。
- 开启双写,老库和新库同时写入。注意:任何对数据库的增删改都要双写;对于更新操作,如果新库没有相关记录,需要先从老库查出记录,将更新后的记录写入新库;为了保证写入性能,老库写完后,可以采用消息队列异步写入新库。
- 利用脚本程序,将某一时间戳之前的老数据迁移到新库。注意:1,时间戳一定要选择开启双写后的时间点(比如开启双写后10分钟的时间点),避免部分老数据被漏掉;2,迁移过程遇到记录冲突直接忽略(因为第2步的更新操作,可能已经把记录拉到了新库);3,迁移过程一定要记录日志,尤其是错误日志,如果有填写失败的情况,我们可以通过日志恢复数据,以此来保证新老库的数据一致。
- 第3步完成后,我们还需要通过脚本程序检验数据,看新库数据是否准确以及有没有漏掉的数据
- 数据校验没问题后,开启双读,起初给新库放少部分流量,新库和老库同时读取。由于延时问题,新库和老库可能会有少量数据记录不一致的情况,所以新库读不到时需要再读一遍老库。逐步将读流量切到新库,相当于灰度上线的过程。遇到问题可以及时把流量切回老库
- 读流量全部切到新库后,关闭老库写入(可以在代码里加上热配置开关),只写新库
- 迁移完成,后续可以去掉双写双读相关无用代码。
利用数据同步工具
我们可以看到上面双写的方案比较麻烦,很多数据库写入的地方都需要修改代码。有没有更好的方案呢?我们还可以利用Canal,DataBus等工具做数据同步。以阿里开源的Canal为例。
上面是Canal的原理图
- Canal模拟mysql slave的交互协议,把自己伪装成mysql的从库
- 向mysql master发送dump协议
- mysql master收到dump协议,发送binary log给slave(canal)
- canal解析binary log字节流对象,根据应用场景对binary log字节流做相应的处理
所以上面的用户系统数据迁移,就不需要开启双写了,服务层也不需要编写双写的代码,直接用Canal做增量数据同步即可。相应的步骤就变成了:
- 代码准备。准备Canal代码,解析binary log字节流对象,并把解析好的用户数据写入新库。准备迁移程序脚本,用于做老数据迁移。准备校验程序脚本,用于校验新库和老库的数据是否一致。
- 运行Canal代码,开始增量数据(线上产生的新数据)从老库到新库的同步。
- 利用脚本程序,将某一时间戳之前的老数据迁移到新库。注意:1,时间戳一定要选择开始运行Canal程序后的时间点(比如运行Canal代码后10分钟的时间点),避免部分老数据被漏掉;3,迁移过程一定要记录日志,尤其是错误日志,如果有些记录写入失败,我们可以通过日志恢复数据,以此来保证新老库的数据一致。
- 第3步完成后,我们还需要通过脚本程序检验数据,看新库数据是否准确以及有没有漏掉的数据
- 数据校验没问题后,开启双读,起初给新库放少部分流量,新库和老库同时读取。由于延时问题,新库和老库可能会有少量数据记录不一致的情况,所以新库读不到时需要再读一遍老库。逐步将读流量切到新库,相当于灰度上线的过程。遇到问题可以及时把流量切回老库
- 读流量全部切到新库后,将写入流量切到新库(可以在代码里加上热配置开关。注:由于切换过程Canal程序还在运行,仍然能够获取老库的数据变化并同步到新库,所以切换过程不会导致部分老库数据无法同步新库的情况)
- 关闭Canal程序
- 迁移完成
此外,对于数据结构不改变的不停机数据迁移,也可以利用Canal处理。除了第3步DBA可以直接利用工具做老数据的迁移,其他步骤基本和上面一样。
阿里云的数据传输服务DTS
数据传输服务(Data Transmission Service,简称DTS)是阿里云提供的一种支持 RDBMS(关系型数据库)、NoSQL、OLAP 等多种数据源之间数据交互的数据流服务。DTS提供了数据迁移、实时数据订阅及数据实时同步等多种数据传输能力,可实现不停服数据迁移、数据异地灾备、异地多活(单元化)、跨境数据同步、实时数据仓库、查询报表分流、缓存更新、异步消息通知等多种业务应用场景,助您构建高安全、可扩展、高可用的数据架构。
优势:数据传输(Data Transmission)服务 DTS 支持 RDBMS、NoSQL、OLAP 等多种数据源间的数据传输。它提供了数据迁移、实时数据订阅及数据实时同步等多种数据传输方式。相对于第三方数据流工具,数据传输服务 DTS 提供更丰富多样、高性能、高安全可靠的传输链路,同时它提供了诸多便利功能,极大得方便了传输链路的创建及管理。
个人理解:就是一个消息队列,会给你推送它包装过的sql对象,可以自己做个服务去解析这些sql对象。
阿里文档快速入口:https://help.aliyun.com/product/26590.html
免去部署维护的昂贵使用成本。DTS针对阿里云RDS(在线关系型数据库)、DRDS等产品进行了适配,解决了Binlog日志回收,主备切换、VPC网络切换等场景下的订阅高可用问题。同时,针对RDS进行了针对性的性能优化。出于稳定性、性能及成本的考虑,推荐使用。
附datagrip导出数据
边栏推荐
- Wechat reading notes of "work, consumerism and the new poor"
- MySQL数据库基本操作-DDL | 黑马程序员
- Hough Transform 霍夫变换原理
- Shell programming core technology "four"
- Hough transform Hough transform principle
- Pointnet/Pointnet++点云数据集处理并训练
- Go microservice (II) - detailed introduction to protobuf
- DeFi生态NFT流动性挖矿系统开发搭建
- Crawler (6) - Web page data parsing (2) | the use of beautifulsoup4 in Crawlers
- 明明的随机数
猜你喜欢
Upgrade the smart switch, how much is the difference between the "zero fire version" and "single fire" wiring methods?
The latest progress of Intel Integrated Optoelectronics Research promotes the progress of CO packaging optics and optical interconnection technology
Go微服务(二)——Protobuf详细入门
PointNeXt:通过改进的模型训练和缩放策略审视PointNet++
OpenCV的二值化处理函数threshold()详解
There are multiple divs in the large div, which are displayed on the same line. After overflow, scroll bars are generated without line breaks
2022CoCa: Contrastive Captioners are Image-Text Fountion Models
Hough transform Hough transform principle
用实际例子详细探究OpenCV的轮廓绘制函数drawContours()
The 300th weekly match of leetcode (20220703)
随机推荐
Have you guys ever used CDC direct Mysql to Clickhouse
Lenovo explains in detail the green smart city digital twin platform for the first time to solve the difficulties of urban dual carbon upgrading
node_exporter部署
Technology sharing | interface testing value and system
php伪原创api对接方法
牛客小白月赛7 谁是神箭手
2014 Hefei 31st youth informatics Olympic Games (primary school group) test questions
整理混乱的头文件,我用include what you use
Is it safe to open an account at Great Wall Securities? How to open an account when buying stocks
LM10丨余弦波动顺势网格策略
自由小兵儿
牛客小白月赛7 I 新建 Microsoft Office Word 文档
【问题】druid报异常sql injection violation, part alway true condition not allow 解决方案
LeetCode FizzBuzz C#解答
OpenCV的二值化处理函数threshold()详解
问下各位大佬有用过cdc直接mysql to clickhouse的么
Other InterSystems%net tools
《看完就懂系列》字符串截取方法substr() 、 slice() 和 substring()之间的区别和用法
使用canal配合rocketmq监听mysql的binlog日志
Explore the contour drawing function drawcontours() of OpenCV in detail with practical examples