支付公司的系统迁移技术方案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
支付公司的系统迁移技术方案
互联网金融行业发生了翻天覆地的变化,相对应的金融科技也在不断的更新和迭代,每次有新的软件系统出炉的时候,就是老的软件系统命运终结的开始,老的项目当然不会束手就擒,它也会做最后的挣扎,当你从它身上迁移用户或者商户的时候,它会给你带来很多麻烦,比如说,它会临时罢工、出现资金损失等等不可忽视的问题,因此,迁移是个大任务,有的时候迁移并不亚于开发一套新系统的难度,甚至可以说是有过之而无不及。
哪些场景需要迁移
我们总结了各种需要迁移的场景。
字段迁移
原来设计的字段大小不能满足现在业务的需求,直接在原表上扩容字段可能会影响线上跑的业务,因此,我们需要增加一个字段来替换原来的字段;字段的数据格式需要升级,通过新增字段来替换原有字段,例如:原有未加密的字段处于安全需求进行加密。
表迁移
用于数据库表设计重构的场景,原有表的结构不合理,新增合理的表来替换原有的表,这时候我们需要表迁移。
数据库迁移
把单库迁移到分库分表的多个库;从一种数据库迁移到另外一种数据库;分库分表的多个库需要扩容的时候,需要进行数据库迁移,迁移到一套能够容纳足够数据的数据库集群。
数据库迁移到其他类型的库
对数据库的选型发生了变化,例如:微博的粉丝库从原有的MySQL 迁移到HBase。
系统迁移
原有系统的技术已经过时了,不能满足新需求或者业务发展的需要,开发完成新系统来替换原有系统。通用的迁移方法论
通用的迁移方法分为平滑迁移和停机迁移,平滑迁移一般采用双写的方案,不需要停机就可以完成迁移,类似飞机的空中加油,或者给运行的汽车换轮子。而停机迁移,则需要停止现有的业务服务,然后迁移数据,待数据迁移之后,再开启对外提供服务。
这里讲解的方法论是一种通用的迁移方案,既适合字段迁移、表迁移,也适合库迁移以及应用迁移,既适合数据库的迁移也适合缓存的迁移,虽然在细节上有些不同,但是在方法论上则大同小异,我们以分片后的数据容量不能满足需求,需要对分片后的数据扩容为例,这里的扩容实际上是迁移的一种特殊案例,我们以扩容为例来说明相应的步骤和实现细节。
平滑迁移
平滑迁移适合对可用性要求较高的场景,例如,线上的交易服务对缓存或者数据库依赖较大,不能忍受停机带来的业务损失,也没有交易的低峰期,我们对此只能采用平滑迁移的方式。
平滑迁移,是指将正在提供线上服务的数据,从一个地方数据存储到另一个数据存储,整个迁移过程中要求不停机,服务不受影响。根据数据所处层次,可以分为缓存迁移、数据库存储迁移、应用迁移
等等;根据数据迁移前后的变化,又可以分为数据平移和数据转移。数据库对数据库的迁移属于平移,数据库对其他NoSQL 库的迁移属于数据转移。
数据平移是指迁移前后数据组织形式不变,比如MySQL 数据库从1个实例扩展为4个实例,Redis 缓存从2个实例扩展到8个实例等等。
如果在最初的设计里就为以后的扩容做好准备,也就是做了充分的容量评估(关于容量评估,请参考《分布式服务架构:原理、设计与实战》一书中第3章的内容),那么数据迁移工作就会简单很多,比如MySQL 已经做了分库分表,扩展实例的时候,只需要多做几个从库,切换访问关系,最后将冗余的库表删除即可达到扩容的效果,当然,这需要短暂的停止服务。
近年来出现很多支持自动可伸缩的数据库,在实现上已经做到全自动数据迁移,如HBase、TiDB 等,那就更简单了,只要通过管理功能来添加机器,手工修改配置或者系统自动发现,就可完成数据库容,也就免去了复杂的数据迁移等工作。
数据转移是指在数据迁移前后,数据组织形式发生了变化。比如将MySQL 数据库迁移到HBase 数据库,微博就经历过这样的过程。
平滑迁移通常使用的是双写方案,方案分成4个步骤:双写、迁移历史数据、切读、下双写。
这种方式如果应用于缓存扩容的迁移场景,则还有一个变种,就是不需要迁移旧数据,在第1步中双写后,在一定的时间里通过新规则对新缓存进行写入,新缓存已经有了足够的数据,这样我们就不用再迁移旧数据,直接进入第3步即可。
首先,假设我们的应用现在使用了具有两个分片的数据集群,通过关键字哈希的方式进行路由,如下图所示。
因为两个分片已经不能满足容量的需求,所以现在需要扩容到4个分片,达到原来两倍的总大小,因此我们需要迁移。
迁移的具体过程如下。
(1)双写
按照新规则和旧规则同时往新旧数据系统中写数据,如下图所示。
这里,我们仍然按照旧的规则,也就是关键字哈希除以2取余来路由分片,同时按照新的规则,也就是关键字哈希除以4取余来路由到新的4个分片上,来完成数据的双写。
这个步骤有优化的空间,因为是在成倍扩容,其实,我们不需要准备4个全新的分片,对于新规则中的前两个分片的数据,其实是旧规则中的两个分片数据的子集,并且规则一致,所以我们可以重用前两个分片,也就是一共需要两个新的分片,用来处理关键字哈希取余后为2和3的情况,使用旧的数据分片来处理关键字哈希取余后0和1的情况即可。如下图所示。
(2)迁移历史数据
把旧缓存集群中的历史数据读取出来,按照新的规则写到新的数据集群中,如下图所示。
在这个过程中,我们需要迁移历史数据,在迁移的过程中可能需要迁移工具,这也需要一部分开发工作量。在迁移后,我们还需要对迁移的数据进行验证,表明我们的数据迁移成功。
在某些应用场景下,例如缓存数据,并不是应用强依赖的,在缓存里获取不到数据,可以回源到数据库获取,因此在这种场景下通过容量评估,数据库可以承受回源导致的压力增加,就可以避免迁移旧数据。
在另一种场景下,数据一般是具有时效性的,应用在双写期间不断向新的集群中写入新数据,历史数据会逐渐过时,并被从旧的集群中删除,在一定的时间流逝后,新的集群中自然就有了最新的数据,就不再需要迁移历史数据了,但是这需要进行评估和验证。
(3)切读
把应用层所有的读操作路由到新的数据集群上,如下图所示。