作者:闲鱼技术-齐悟
背景
在阿里巴巴内部“大中台,小前台”的组织和业务*,使前线业务更加敏捷,赋能业务积极迎接未来挑战和机遇,在阿里大中台能力建设过程中,同质化中台服务将会合并,小前台需要迁移原来依赖的中台服务到新的中台服务上。闲鱼作为小前台,依赖阿里巴巴大中台能力让产品快速迭代,其中闲鱼币依赖的就是阿里巴巴积分中台能力。在积分能力大中台建设过程中,原有的积分服务都将合并到“半两”积分平台,闲鱼币原来依赖的积分平台是"KingTower"积分平台,目前"KingTower"即将下线,所以闲鱼币需要把数据和依赖的服务迁移到“半两”积分平台。
现状
闲鱼币存量用户过亿,每日新增闲鱼币用户万级别,闲鱼币操作次数过亿。
一般数据迁移是通过数据库相关工具进行操作,具体可以参考《21世纪了还愚公移山?数据库这么迁移更快!》。但闲鱼币数据迁移却不同,首先“KingTower”平台的数据结构和“半两”平台的数据结构不同;其次出于对数据安全和稳定性的考虑,两个积分平台只对外提供服务接口,不允许业务方直接操作平台数据库。这就意味着闲鱼币迁移无法利用数据库工具,只能通过两个平台提供的服务接口完成迁移工作。本文将结合闲鱼币迁移过程,提供一种基于服务接口的数据迁移方案,在用户无感知的情况下完成迁移目标。
迁移方案
迁移方案主要分为四个步骤,如下图所示,第一步是前期准备,第二步是数据迁移,第三步是服务双写,第四步服务切换,下面将结合闲鱼币的迁移详细介绍这四个步骤:
第一步 前期准备
1.平台能力对齐
新旧平台能力对齐是进行迁移的大前提,如果新的平台能力无法覆盖老的平台的能力,那么需要做的是1.推动新平台提供老平台已有的能力。2.业务方利用新平台提供的已有能力,从业务层实现老平台特有的能力。
2.平台接口对齐
新旧平台接口在出参和入参上会存在一定的差异,差异点寻找具体的操作如下:1.首先列出在使用的老服务接口入参和出参;2.在新服务中找到对应功能的接口,同样列出入参和出参的含义以及数据类型;3.对齐相同含义的参数,并梳理出新接口需要补齐的参数。梳理出接口的差异后需要由业务方补齐两个接口的差异,也就是接下来的业务接口改造。
3.业务接口改造
业务接口改造目的是兼容新老服务接口,补齐新服务缺少的入参项,对齐新服务和老服务的出参,同时要注意的是新老服务对入参的检测,防止可接受参数取值范围不同,业务接口改造完成后,对调用该业务接口的整个业务链路进行改造和验证,保证对原有的业务和产品逻辑不造成影响。
在闲鱼币迁移的场景中,平台能力对齐上,新老积分服务都提供了积分的查询、增加、扣除的能力,但是老积分平台在这些基础上封装了一些通用的玩法,在闲鱼币中使用了其提供的签到能力,所以需要在业务层利用新平台的积分增加能力,实现闲鱼币签到能力。在平台接口对齐上,虽然老服务和新服务入参的参数名不同,但老服务入参可以完全覆盖新服务入参,但是差异点在老服务不接受用户账户扣除到负数,但是新服务中支持。同时为了兼容上层的业务,闲鱼币秦阿姨过程对两个服务进行了封装,保证上层业务无感知。
第二步 数据迁移
在迁移过程中,分为两种情况一种是用户触发式迁移称为主动迁移,一种是由系统发起的迁移称为被动迁移,两种迁移方式对于用户来讲都是无感知迁移,具体数据迁移方案如下所示。
1.主动迁移
主动迁移是由用户触发,当用户进行积分增减操作的时候,将先触发迁移流程,首先用户读取迁移标志,如果完成迁移则无需再次迁移;然后获取全局积分增减操作锁,目的是防止在迁移过程中有其他增减操作造成数据不一致;接着读取老积分,并把读取的积分写入到新积分服务,然后迁移完成的标志位,至此一个用户的账户迁移完成;最后释放全局锁。
2.被动迁移
被动迁移是由系统触发,系统首先计算出需要迁移的用户列表,同时利用分布式任务系统把需要迁移的用户分发到各个机器上,后续迁移流程与用户主动迁移一样,读取迁移标识、获取全局锁、读旧写新、写入迁移标识、释放锁,完成整个迁移过程。
主动迁移和被动迁移最终目的都是把用户数据从老积分账户数据迁移到新积分上,两种方式各有自己的应用场景,主动迁移主要适用于迁移活跃用户和新增用户,被动迁移主要适用于迁移存量用户。两种迁移遇到的技术难点是一样的。
第一并发处理,在上面两种方案只展示了迁移过程中要获取全局分布式锁,对于未迁移的用户在进行加减操作时候同样也要获取全局锁,具体如下图所示,这样才能保证迁移过程中不产生脏数据,本文中的全局锁使用的是Redis实现,这里不再赘述。
第二操作事务性,本文的迁移方案中只有当写入迁移完成标记才算是迁移成功,在这一步前的其他每一步都有可能由于RPC调用产系统异常或超时错误,所以为了保证操作事务性,对于任何一步出错本次迁移都算失败,失败的用户将会进行下面的迁移重试流程。
在闲鱼币迁移过程中采用了被动迁移和主动迁移两种方式,被动迁移用来解决迁移存量用户,主动迁移用来解决迁移新增用户,在被动迁移过程中通过控制计算离线人群来实现逐步迁移,在主动迁移过程中通过白名单和控制用户尾号逐步放量的方式控制迁移过程,逐步放量可以保证迁移出现的问题早发现早解决。
第三步 服务双写
1.双写新旧平台
当用户数据迁移完成后,需要即刻对新老服务进行双写,双写逻辑如下图所示,首先验证用户是否已是迁移的用户,如果是迁移的用户,那么先写老积分,写老积分成功后写新积分,完成双写逻辑。在双写过程中为了防止写老服务写入成功返回超时和写新积分失败的情况,在老积分服务中定制了异步逻辑,即老积分系统中在用户操作积分加减成功后会发出成功的消息,消息中会有幂等Key,业务方接收到消息后,根据幂等Key判断新积分服务中是否已对该Key进行过相关操作,如果没有操作过那么将会在新积分服务中操作,实现数据的最终一致性
2.对账服务
对账是迁移的重要一步,通过对账可以验证出迁移数据在新老平台上是否一致,对账流程如下图所示,通过定时任务轮询执行已经完成迁移的用户在新老平台的数据一致性。需要注意的是由于读取新老平台有先后顺序,所以产生瞬时的数据不一致,对于这种问题可以采用对账重试,只要保证最终一致即可。
闲鱼币迁移过程中数据迁移和双写是同步进行的,迁移成功的标志也是开始双写的标志,按照正常的业务逻辑在对账环节不会出现大面积对账不一致情况,如果出现大面积对账不一致并且对账重试后无法解决,那么就是在数据迁移和双写的过程出现了问题,此时需要停止迁移排查问题,同时整个迁移过程提供了可回滚能力能力,闲鱼币迁移中的迁移标志和新积分平台数据都是可以进行重置的,重置后即可从头开始二次迁移,不会对用户造成影响。
第四步 服务切换
完成以上三个步骤基本完成了数据的迁移工作,下面要做的就是停掉老服务,切换到新的服务上去。具体方式如下图所示:
切换过程采用逐步放量的形式,灰度方式很多我们采用的是先白名单验证,然后用户ID取模1000逐步放量的方式。值得注意的一点是读灰度和灰度要分开进行,当对账没有问题的时候就可以开启读灰度了,在读灰度过程中仍旧保持双写,此时如果读灰度发现问题,仍旧可以回滚会老的服务。但是单写新服务开始后就无法进行回滚,所以在写灰度前需要充分白名单验证。
总结
本文介绍了闲鱼币从老积分平台迁移到新积分平台整个过程,总结了基于服务的数据迁移方案,同时在介绍了闲鱼币迁移时候遇到的问题以及解决方案,整个迁移过程从方案制定到最终的迁移完成持续约一个月时间,最终在用户没有感知的情况下完成闲鱼币的迁移。与数据库迁移相比,从服务接口对数据迁移有如下优势:1.无需关心底层数据存储,只需做好上层业务逻辑兼容即可。2.迁移过程可控,通过多维度的迁移监控及早发现问题。但是也有如下的不足:1.迁移过程受到服务方QPS限制,迁移周期长 2.迁移过程都是RPC调用,需要处理多种异常情况。无论是利用数据库工具还是利用服务对数据进行迁移,目标都是一致的那就是数据无差异,用户无感知,异常可监控,方案可回滚。