[转载]在线数据迁移经验:如何为正在飞行的飞机更换引擎

转载自:http://www.infoq.com/cn/articles/online-data-migration-experience

在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为cache迁移和存储迁移;根据数据迁移前后的变化,又可以分为平移和转移。

平移是指迁移前后数据组织形式不变,比如Mysql从1个实例扩展为4个实例,Redis从4个端口扩展到16个端口,HBase从20台机器扩展到 30台机器等等。如果在最初的设计里就为以后的扩容缩容提供了方便,那么数据迁移工作就会简单很多,比如Mysql已经做了分库分表,扩展实例的时候,只需要多做几个从库,切换访问,最后将多余的库表删除即可。更进一步,在实现上已经做到全自动数据迁移,如 HBase,就更简单了:添加机器,手工修改配置或者系统自动发现,然后,沏一杯咖啡,等待系统完成迁移。

转移是指数据迁移前后,数据组织形式发生了变化。多年前,某社交平台曾经为ID升级做过一次数据迁移,将ID由最初的自增算法修改为巧妙设计的UUID算法,这次迁移最大的挑战是要修改数据的主键,主键本来是数据的唯一标识,它发生变化,也就意味着原来的数据不复存在,新的数据凭空产生,对于整个系统中所有业务流程、周边配套、上下游部门都会产生巨大的兼容性挑战。不过大部分数据迁移项目都不会修改主键,甚至不会修改数据本身,改变的只是数据的组织形式。比如某社交平台计数器原本为了节约存储空间,使用redis hash进行存储,后来为了提升批量查询的性能,迁移成 KV 形式;又比如某社交平台的转发列表和粉丝列表,最初都使用Mysql存储,后来为了更好的扩展性和成本,都迁移到HBase存储。

 

在线数据迁移一般分为四个步骤:一,上线双写,即同时写入新旧两种数据;二,历史数据离线搬迁,即离线将历史存量数据从旧系统搬到新系统;三,切读,即将读请求路由到新系统;四,清理沉淀,包括清理旧的数据,回收资源,及清理旧的代码逻辑,旧的配套系统等等,将迁移过程中的经验教训进行总结沉淀,将过程中开发或使用的工具进行通用化改造,以备下次使用。注意,某些情况下,步骤一和步骤二也可能倒过来,先做历史数据搬迁,然后再写入新数据,这时候就需要谨慎的处理搬迁这段时间里产生的新数据,一般使用 queue 缓存写入的方式,称为“追数据”。在线数据迁移最大的挑战是如何保证迁移过程服务不受影响。很多人将其比喻成“飞行过程中换发动机”“给行驶的汽车换轮胎”,但实际上并没有那么困难,一个入行一两年的技术人员,遵从一些经验指导,完全可以完成。下面就跟大家分享一下个人在这方面的一些经验,作为抛砖引玉。

 

图1:在线数据迁移步骤示意图

下面以某社交平台粉丝列表从Mysql迁移到HBase为例子,展开来讲讲每个步骤具体实施、可能的问题及对策。

在迁移之前,根据以往的经验制定了更详细的流程,如图:

图2:粉丝列表迁移到HBase工作流程图

上线双写

编写双写的代码逻辑之前,首先要根据业务规则和性能指标确定HBase的表结构和主键设计。  
对于列表类的需求,HBase有两种典型的用法,一种是高表模式,与传统的Mysql模式非常类似,列表中的每一项存一行,每一行有固定的属性列;另一种是宽表模式,一个列表存一行,列表中的每一项存成一个单独的列,各种属性都打包到列内部的value中。如图:

图3:粉丝列表业务分别使用HBase高表模式和宽表模式存储示意图

高表模式的好处在于与Mysql类似,各种业务逻辑的实现也比较像,认知和改造成本较低,劣势在于因为HBase的实现机制导致单个列表可能被分别存储在多个不同的Region里,查询的性能较差。而宽表的优劣势正好与高表相反。在高并发大流量系统中,技术方案很多特性都可以妥协,但唯独性能永远是不能妥协的,所以我们选择宽表模式。

很多高并发系统都采用上行异步化,通过将操作转化为消息,写入消息队列,后台异步处理的方式来削峰填谷,并获得更好的可用性。大部分消息队列都支持单个消息被多个业务模块重复处理,并支持串联和并联。所以在这里我们将写入HBase的代码逻辑单独封装到一个模块中,将它配置为与写入旧Mysql代码串联或并联即可。

为了支持消息异步处理的重试机制,建议将业务模块设计成具有幂等特性,即同一条消息可以重试多次,而不会破坏最终的结果。有一些模块,如计数器,提醒等,业务本身不支持重试,可以通过“重复消息检测模块”为它们提供短时间内的重试支持。大部分Mysql存储都通过主键或者单独的Unique key索引来达到幂等要求,相应的,HBase高表模式通过主键保证,宽表模式通过column qualifier保证。在粉丝列表迁移过程中,因为column qualifier不能保证幂等,导致数据一致性无法达到要求,最后也是通过引入额外的重复消息检测模块解决。

另外,HBase当前不提供二级索引、覆盖索引、join、order by等Mysql高级查询功能,需要在迁移之前做好评估,确定新方案能够支持所有的业务特性。比如粉丝列表一般都是查询最新的5000个粉丝,但如果还要支持查询最初100个粉丝列表的功能,就会比较费劲。

上线双写完成后,需要对双写的数据进行一致性校验。数据一致性校验需要从两个维度进行:存储维度和业务维度。存储维度是指直接取Mysql和HBase里的数据进行对比;业务维度是指从最终用户看到的数据维度进行校验,即访问粉丝列表页面,看结果是否与原来一致。大型系统的数据一致性校验建议及格线是6个9,即99.9999%,也就是说每一百万条数据中,差别不能超过1条。

历史数据搬迁

上线双写并校验确认通过后,就可以开始搬迁历史数据了。

搬迁历史数据的步骤中,最大的困难是保证搬迁过程与线上业务写入互不干扰。对于列表类功能,最大的干扰是来自于这样一种业务场景:搬迁程序从Mysql中select出来一个列表,在插入到HBase之前,这个列表发生了变化。如果是增加一个元素,由于HBase的幂等保证,最终结果并不会产生偏差,但如果是删除一个或多个元素,那么最终会表现为HBase中删除操作未生效,因为线上业务执行完删除操作后,搬迁程序又执行了插入操作。本质上,这是因为我们在这样的数据量规模下不能使用事务引起的,如果引入事务,能够解决这个问题,但同时也会将搬迁耗时从几天延长到几周甚至几个月。为了解决这个问题,可以通过引入轻量级的Memcache锁来模拟Serializable级别的事务隔离。

历史数据搬迁完成后也需要进行一致性校验。实际上,建议在搬迁全量数据之前,先搬迁部分数据,并进行一致性校验。部分数据一致性校验通过后,再对全量数据进行搬迁。这种方式可以极大的节约搬迁时间,降低因为搬迁流程或代码不完善导致的延期风险。

切读

全量数据搬迁并校验完成后,即可以进行读请求切换了。通用的切换方式是在代码中埋入开关,通过 Config Service 或类似机制进行切换操作。切换的流程为:Tcpcopy环境 --> 线上环境 uid 白名单(内部工程师)--> 线上环境百分比灰度 0.01%,1%,10% --> 线上环境全量。tcpcopy 环境用来验证代码在线上环境是否正常,uid白名单用来验证功能是否正常,百分比灰度用来验证性能和资源压力是否正常,所有验证都通过后,最后才进行全量切换。一般这个过程会持续一周到两周。

清理沉淀

切读完成后,整个数据迁移过程可以认为已经完成了。但项目工作并没有完结,旧的逻辑代码清理,旧的配套系统下线,旧资源回收,以及最重要的一个环节:经验教训总结、分享,流程完善,工具通用化改造。

在线数据迁移并不是一项需要高深技术的工作,它更多需要的是对业务逻辑的把控,对操作流程的理解,对新旧系统特性的掌握,以及对细节的敬畏之心。


感谢郭蕾对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家通过新浪微博(@InfoQ)或者腾讯微博(@InfoQ)关注我们,并与我们的编辑和其他读者朋友交流。

X-Plane/Plane-Maker 官方教程 X-Plane/Plane-Maker 官方教程,一步一步教你如何在 Plane-Maker 中打造属于自己的飞行器。 立即下载

相关推荐

Centos7网络配置(设置固定ip)

刚安装完系统,有的人尤其没有勾选自动网络配置的情况下,是访问不了外网的,本机也连不通虚拟机。或者现在有的是动态ip,几次之后启动ip地址就变了,会导致其他软件或程序之前连接配置要重新更改,很麻烦,下面讲解一下如何配置网络,如何设置成固定ip。

个人笔记git:https://gitee.com/tlangp/note.git 8053

如何做数据平滑迁移:双写方案

数据迁移指的是将一批数据从同构存储系统(如MySQLA到MySQLB)或异构存储系统(如MySQL-MongoDB)间搬运迁移。数据双写迁移是最常用的一种数据迁移方案,可以保证迁移过程是在线的、迁移前后数据是一致的、迁移过程是可回滚的。数据双写迁移方案分为五大步,分别是:同步、双写、校验、切读、切写。...

BoringError的博客 1万+

UE4入门实例17(Unreal制作卡通Post Process材质球)

效果展示 #1 创建Post Porcess材质球 #2 编写Shader功能 #3 设置场景区域内风格化渲染 #1 创建Post Porcess材质球 #2 编写Shader功能 创建基础效果 移除现有通道渲染 设置视图渲染范围 #3 设置场景区域内风格化渲染 #4 加群下载Shader源码:284105567 ...

Unity3d 攻城师一枚 1345

双写实现数据迁移

埋点将变更对象id记录和原修改记录保持事物提交。性能损耗低。 记录当前表中数据自增id的最大值,开始通过自增id,开始同步数据,当前记录自增id结束。 开启遍历2阶段记录id,将数据同步过来。开启双写更新,新写方案(新增数据,双写同步新增,不记录新增数据id。数据变更,新写中更新,如果数据自增id,不在变更数据id范围内,两边同步更新)。 数据变更直到id的记录被同步完成。上线读取切换之后服务,读取切换完成之后,切换写过程。 整个切换完成。

A627292959的博客 1666

HDR标准核心参数全解析:从PQ/HLG到元数据,一篇搞懂技术选型

本文全面解析HDR标准的核心参数,包括PQ/HLG传输函数和元数据机制,帮助读者理解技术选型的关键因素。通过对比主流HDR标准的技术细节,提供从内容创作到硬件适配的实用指南,助力实现更真实的视觉体验。

weixin_31766003的博客 300

An工具介绍之摄像头

An工具介绍之摄像头

人生得意须尽欢 6185

双写数据一致性:保障数据生命线的关键

保障双写数据一致性是一个复杂的问题,需要根据具体的业务场景、性能要求、成本预算等因素选择合适的方案。本文介绍了一些常用的策略和方法,包括事务保证、异步重试机制、消息队列、Canal + MQ、补偿机制、幂等性设计、读写分离 + 数据校验等。希望这些信息能帮助你更好地理解如何保证双写数据一致性,构建可靠的分布式系统。

q68686的博客 1405

Windows 10/11下彻底卸载Chrome的终极指南(附一键清理注册表脚本)

本文提供了一份在Windows 10/11系统中彻底卸载Google Chrome浏览器的终极指南。针对标准卸载后用户数据与注册表项残留的问题,文章详细介绍了从应用程序层、用户数据层到系统集成层的三层深度清理方法,并重点提供了安全高效的注册表清理脚本,确保浏览器所有痕迹被完全移除,解决重装冲突并释放磁盘空间。

elastic6hunter的博客 782

云时代架构--阅读笔记02

  作者以飞机更换引擎为例来向我们展示了一个,如何给针对一个飞速发展的系统进行大幅度的改造,可以通过将All-in-one的架构改造成微服务架构,来尽可能减少或消除停服的时间。 一般重构的分类分为3种: 彻底重新做,直接从前到后抛弃老系统。 大规模重构,保留对用户的这层皮,后面从服务到数据全部替换 小规模重构,保留对用户的这层皮以及数据结构,逐一替换核心逻辑到微服务 在更换...

weixin_30725467的博客 99

产品必备技能(十):如何绘制原型图?先要绘制页面流程图+页面原型图!附实操原型图、流程图实例(抖音)

文章目录目标题目实操步骤模板实操【抖音】APP的视频发布功能页面流程绘制页面流程图合格标准绘制页面原型图合格标准 目标 新入行的产品经理都对原型抱有向往的心境,但是有经验的产品经理不会一上来就画原型,而是先画页面流程再来画原型。通过学习,你将学会如何用页面流程图规划用户行为路径、如何借助原型识别问题、减少风险、有效沟通。 题目 任意选择一款你喜欢的产品,体验某个功能,下载并梳理此功能至少5个以上的页面流程跳转点(后面会解释),还原2 - 3个主要界面的低保真原型图。 实操步骤 可使用手绘以及Process

汪雯琦的博客 4841

逆变器、转换器、DCDC、继电器等器件的原理和作用

交流电变成直流电的过程:整流==》滤波==》稳压。

m0_61973119的博客 8028

数据迁移:双写调研

注:没有实践过,完全是为了学习 目的 目的:将A库中N张表中的数据迁移到B库的M张表中,在B库中做分表操作。在迁移过程中要求不停服。 方案 方案:双写 具体流程 在B库中建表,在代码中实现双写的开关以及功能(读老库,增删改老库和新库) 由于只读老库,所以新库中的功能实际上未对外提供数据,即使期间新库数据存在问题,依旧不影响服务功能 新增操作:老库和新库都新增,因此新增的数据新老库是一致的。(新老库自动生成的主键不一致问题,可以先插入老库,得到id,再插入新库,插入数据带上id) 删操作:删除操作幂等,

gentlezuo的博客 2769

【论文精读】《Towards Deep Learning Models Resistant to Adversarial Attacks》

本文探讨了深度学习模型在面对对抗性攻击时的脆弱性,并提出了一种基于鲁棒优化的方法来增强神经网络的对抗鲁棒性。通过鞍点优化框架,作者提供了对抗攻击和防御机制的统一视角,并在MNIST和CIFAR-10数据集上验证了其方法的有效性。对抗训练的核心思想是将对抗样本引入训练过程,使模型能够学习到对抗样本的特征,从而提升其鲁棒性。本文通过鞍点优化框架提出了一种基于鲁棒优化的对抗训练方法,显著提升了深度学习模型的对抗鲁棒性。本文为深度学习模型的对抗鲁棒性研究提供了新的理论和实证支持,同时为未来研究指明了方向。

nmdbbzcl的博客 611

mysql数据迁移双写_【数据迁移】在线数据迁移 :双写数据库、搬历史数据、切换写入、灰度验证(99.9999%)、删除历史-Go语言中文社区...

在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为cache迁移和存储迁移;根据数据迁移前后的变化,又可以分为平移和转移。平移是指迁移前后数据组织形式不变,比如Mysql从1个实例扩展为4个实例,Redis从4个端口扩展到16个端口,HBase从20台机器扩 展到 30台机器等等。如果在最初的设计里就为以后的扩...

weixin_30054883的博客 944

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

给飞行中的飞机换发动机

程序猿成长必经之路 动力不足问题 在长期的工作生活中,特别是大型互联网公司中,压力一般较大,特别作为女生,面对长期加班,身体素质每况愈下,升职加薪也没有男孩子顺畅的情况下,很容易让女程序员失去奋斗的动力,以致后面萎靡不振,对自己失去信心,甚至产生怀疑,暗自嗟叹自己是否适合继续走程序员这个条路。 还有一种情况是自己本来计算机基础不够扎实,虽然依靠学历背景或者就业前的突击赢得了一份不错的工作机会,但是...

changhong52的博客 893

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

在线数据迁移实践:如何为正在飞行的飞机更换引擎

在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为 cache 迁移和存储迁移;根据数据迁移前后的...

a934079371的博客 350

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

在线数据迁移经验:如何为正在飞行的飞机更换引擎

在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为cache迁移和存储迁移;根据数据迁移前后的变化,又可以分为平移和转移。 平移是指迁移前后数据组织形式不变,比如Mysql从1个实例扩展为4个实例,Redis从4个端口扩展到16个端口,HBase从20台机器扩展到 30台机器等等。如果在最初的

pecywang的专栏 833

【数据迁移】在线数据迁移 :双写数据库、搬历史数据、切换写入、灰度验证(99.9999%)、删除历史

步骤:双写数据库、搬历史数据、切换写入、灰度验证(99.9999%)、删除历史;  在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为 cache 迁移和存储迁移;根据数据迁移前后的变化,又可以分为平移和转移。 平移是指迁移前后数据组织形式不变,比如 MySQL 从1个实例扩

ronmy的专栏 1万+

一种在线系统数据迁移方法

高效数据迁移、分布式、多机并行

吖脖(博) 5250

在线数据迁移

在线数据迁移,是指将正在提供线上服务的数据,从一个地方迁移到另一个地方,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为 cache 迁移和存储迁移;根据数据迁移前后的变化,又可以分为平移和转移。 平移是指迁移前后数据组织形式不变,比如 Mysql 从1个实例扩展为 4 个实例,redis 从 4 个端口扩展到 16 个端口,HBase 从 20 台机器扩展到 30

tonyXf121的专栏 3593

高速飞机上换引擎,MQ如何实现平滑迁移?

前几天,杨紫琼同学在知识星球提问,说公司要切换MQ,从一个旧的服务商升级为新的服务商,问有没有什么好方案。这个需求估计还挺普遍的,这里分享一些经验。一、MQ架构简述如上...

shenjian58的博客 1086

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset异常解决

新建了一个项目,数据库连接池采用默认配置,在这种情况下长时间不访问,然而再次访问会报异常: com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset...  网上搜索和问了同事,说是数据库连接池设置不当造成的,在DataSource中加入如下配置:   <!-- 连接池启动时的初始值 --> ...

cwfmaker的专栏 9700
上一篇: Java注解Annotation介绍和使用
下一篇: MySQL日期时间函数大全(转)
cwfmaker
博客等级 码龄18年 6粉丝 179原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值