当前位置:文档之家› 支付公司的系统迁移技术方案

支付公司的系统迁移技术方案

支付公司的系统迁移技术方案互联网金融行业发生了翻天覆地的变化,相对应的金融科技也在不断的更新和迭代,每次有新的软件系统出炉的时候,就是老的软件系统命运终结的开始,老的项目当然不会束手就擒,它也会做最后的挣扎,当你从它身上迁移用户或者商户的时候,它会给你带来很多麻烦,比如说,它会临时罢工、出现资金损失等等不可忽视的问题,因此,迁移是个大任务,有的时候迁移并不亚于开发一套新系统的难度,甚至可以说是有过之而无不及。

哪些场景需要迁移我们总结了各种需要迁移的场景。

字段迁移原来设计的字段大小不能满足现在业务的需求,直接在原表上扩容字段可能会影响线上跑的业务,因此,我们需要增加一个字段来替换原来的字段;字段的数据格式需要升级,通过新增字段来替换原有字段,例如:原有未加密的字段处于安全需求进行加密。

表迁移用于数据库表设计重构的场景,原有表的结构不合理,新增合理的表来替换原有的表,这时候我们需要表迁移。

数据库迁移把单库迁移到分库分表的多个库;从一种数据库迁移到另外一种数据库;分库分表的多个库需要扩容的时候,需要进行数据库迁移,迁移到一套能够容纳足够数据的数据库集群。

数据库迁移到其他类型的库对数据库的选型发生了变化,例如:微博的粉丝库从原有的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)切读把应用层所有的读操作路由到新的数据集群上,如下图所示。

在这一步骤里,把应用中读取的操作的数据源转换成新的数据集群,这时应用的读写操作已经完全发生在新的数据库集群上了。

这一步一般不需要上线代码,我们会在一开始上双写时就实现开关逻辑,这里只需要将读的开关切换到新的集群即可。

(4)下线双写在这一步,我们把写入旧的集群的逻辑下线,如下图所示。

这一步通常是在双写和切读后验证没有任何问题,并保证数据一致性的情况下,才把这部分代码下线。

同时可以把旧的分片下线,如果是扩容的场景,并且重用了旧的分片1和分片2,则还可以清理分片1和分片2中的冗余数据。

对于字段迁移来讲,我们除了新增字段,双写后替换原来字段,我们还可以采用原地替换的方法,对于新数据加密,加密后做标志,然后异步的将历史数据加密,让查询程序兼容加密的数据和非加密的数据。

可以用“软着陆”来形容双写迁移方案,这和新领导上任后,一般先招心腹,慢慢的替代老下属的职责,慢慢淘汰老下属,慢慢实现软着陆如出一辙。

停机迁移停机迁移的方法比较简单,通常分为停止应用、迁移旧数据、更改数据源文件、启动应用这4个步骤,如下图所示。

具体的迁移步骤如下。

1.停机应用,先将应用停止服务。

2.迁移历史数据,按照新的规则把历史数据迁移到新的缓存集群中。

3.更改应用配置,指向新的缓存集群。

4.重新启动应用。

这种方式的好处是实现比较简单、高效,能够有效避免数据的不一致,但是需要由业务方评估影响,一般在晚上交易量比较小或者非核心服务的场景下比较适用。

如何验证迁移成功迁移过程中最重要的一环就是如何验证迁移方案是成功的,我曾经给小伙伴们定了一个顺口溜。

要明确什么样角色的什么人在什么时候到什么系统看到什么样的数据,才能确认迁移成功。

虽然这是看似简单的一句话,但是信息量满满的,有了这句话作为指导,能够确保迁移方案的方向一定是正确的,一定不会导致太大的问题。

这句话具体包括几个要素:谁、什么时候、什么样的数据,这些必须在迁移方案中都要事先明确,具体执行的人必须了解清楚这些条款,假设我们在迁移支付行业中的计费模板,那么迁移切量后,我们就需要计费的运营在切量后的第一时间到计费系统中查看计费的准确性,并且明确什么样的计费结果是准确的,什么样的计费结果是不准确的。

有的时候只靠人来确定数据是否正确恐怕还不够,我们通常需要工具自动化的进行比对,同样我们以计费模板迁移为例,我们从一套计费模板迁移到另外一套计费模板中,通常在初期我们不会真正的以新模板为准,我们会在程序中实现“双计”,既使用老的计费模板计费,也使用新的计费模板计费,在初期我们以老的计费模板为准,新的计费模板计费的结果只用于比对,并且计入日志,这样通过程序自动比对一段时间以后,发现新的计费模板确实没有问题,我们才真的开启开关,以新的计费模板为准。

当然,有的时候数据量巨大,我们比对每一个流量产生的数据不太现实,也会严重影响性能,这个时候我们需要对数据比对进行抽样,只对一些比较有代表性的数据进行比对。

系统迁移后数据清洗系统迁移过程中,上了双写以后,历史数据仍然保留在老系统,因此,我们需要将历史数据迁移到新系统,因为,有些时候我们需要读取或者修改历史数据,例如支付行业的退款等。

我们把迁移历史数据的过程称为洗数据,通常使用如下的步骤来实现。

1.先清洗历史数据,将清洗后的数据写入新系统。

2.做全量对比,如果数据太多,没法全量对比,就抽样对比,看看有没有不一致的数据。

3.在数据量巨大的情况下,线上系统复杂,出现少量的不一致是正常的,这时候不一致的数据进行分析,这时候可能需要参考线上服务系统的交易日志,查明造成不一致的原因,并进行修复。

这里,有读者会对上面第2步有疑问,为什么会产生不一致的数据呢,这有很多原因。

下面我们来仔细分析。

对于增加记录,到迁移历史数据这一阶段,我们使用的是双写,因此,数据在新老数据库中都会存在,即使双写有问题,导致一方不存在,我们也可以通过比对来补齐。

对于更新数据,则容易产生不一致,导致新老数据库的数据不一致,假设在迁移某条历史数据的过程中,线上的交易系统正好修改了这条数据,在双写系统还没有更新历史数据的时候,迁移工具已经把这条数据拿到了应用系统中,这时数据在新老库中都更新了,但是迁移工具后续又把老版本的这条数据更新到新系统中,就导致数据不一致。

对于删除数据,和上面更新数据有一样的问题,也会导致不一致的问题,这时候以谁为准,怎么保证一致性是个难题,我们需要借助修改的timestamp 或者版本来区分哪一个是最新的版本,然后对数据进行修复。

还有另外一个更好的方法,对于某些业务,数据是有一定时效性的,超过一定时间的数据就不再更改,因此,我们可以让双写的时间拉长,要长于数据更新的时间段,这样在历史数据完全不被更新的时候,我们再进行洗数据,就不会因为迁移而产生不一致了。

迁移失败怎么办这里探讨,迁移失败了,迁移后验证迁移有问题了,怎么办?其实,迁移失败了没有什么好的办法,只有两个途径可以走,一个就是迁移失败了就在新系统中修复,但是有些时候这可能会导致更多不可用时间,另外一个方案就是迁移失败了,需要迁移回来,但是迁移回来迁移过程中产生的数据怎么办?这是唯一能用的两个办法,没有更好的办法能解决迁移失败的问题,因此,在这个问题上我们不能奢求完美的解决方案,我们只能退而求其次,提前做好应对方案。

相关主题