系统迁移失败_电商订单迁移方案和关键设计

项目背景

数据迁移指的是数据需要从A迁移到B,之所以需要进行数据迁移,一般是出于2个原因:

  1. 业务整合,比如两条独立的业务线业务重合度高,为了降本增效,需要将AB业务线数据进行融合。
  2. 架构升级:业务发展迅猛导致数据增长量快速,原有架构可能在可预期的不久就无法支撑业务发展,一般应对策略是分库分表,而这就涉及需要将老集群(或老库)数据迁移到新集群(或新库)上。

有些项目可能是出于以上两点原因其中一个,有些可能是2个原因都有,本文就是出于以上2个原因。文章将尝试一步步探讨电商订单迁移方案和关键设计,至于分库分表方案不在本次讨论范围(会单独出一篇技术博文)。

注:在后文的讨论中我们假设数据库使用的是Mysql。

迁移方案

迁移思路

在上一篇《数据迁移方案和关键设计》中,我们探讨了在对象存储领域进行数据迁移的一般解决方案,有它的相同点,有些解决思路我们可以尝试应用到订单迁移项目中。

当开始迁移时,按照对象数据迁移方案,当开始迁移时,我们应该避免老集群产生新订单或有新的数据变更,所有请求都转发到新集群,新集群再决定是否需要从老集群拉取数据,是否需要从老集群获取数据判断依据是请求数据是否在新集群已有。

这种思路完全可以应用于订单迁移项目中,但咱们还得思考一下方案是不是最佳的(或者说这种方案是否存在问题)。

对象迁移方案是先适配如果数据不存在再从老集群读过来,然后在流量低峰进行数据迁移,也就是说还未进行数据迁移前可能会出现大量的同步双读情况,性能double了,我们能否利用缓存的思想,预先准备好数据,尽可能避免双读,这样性能不是就更好了?答案是肯定的,我们完全在开始迁移前将老库订单数据同步到新库(即全量同步),然后利用binlog复制日志进行数据异步增量同步。回过头思考为什么对象迁移方案不这么做?这是因为对象存储系统不像mysql这种关系型数据库系统,没有这种复制日志,对象拷贝到新集群过程中,如果老集群相关对象数据发生变更,新集群无法感知这种变化。【数据预热】

迁移粒度

迁移粒度上,对象存储我们最后的方案是按桶和租户进行数据分区迁移,在订单项目中,可以按用户pin迁移,为了确保安全迁移,可以采用试探策略,提前做好用户pin和对应订单数统计,迁移时先针对订单较少的用户迁移,这样做只因为即使迁移失败(设计方案缺陷or系统bug),影响面也能控制在小范围。【数据迁移分区粒度】

如何避免迁移遗漏,迁移数据不正确?

对象迁移给的方案是迁移进度表,同样,订单迁移也需要一张迁移进度表。当迁移开关打开时,老库不再产生新订单,新订单从新库中插入,这样做可以保证老库用户pin维度订单只是存量订单(total是不变的),不会新增,这就给迁移带来了方便,只需要记录:用户pin、total、position、isFinish等字段就能跟踪迁移进度。这块思路和对象迁移是一致的。

如何保证迁移数据正确?在对象迁移中可以通过校验md5、length判断是否正确;由于本次需求涉及多条业务线订单融合,数据正确性保证应该是在设计阶段确定的。最好的保证方式还是需要程序员在编码阶段和代码review阶段保证字段映射正确。

另外,数据迁移过程中,需要避免数据不一致,双写是禁忌。对象迁移是通过禁止老集群有写流量来保证。其实还有一个思路是主从思路。保证写入的数据只有一个主,从通过异步复制方式来达到和主一致。这样也能避免数据不一致。那为什么对象迁移不用主从方式?这和对象存储业务有关,当对象被覆盖时,从重新和主一致成本太高;二来没有这种异步复制机制,而mysql上述两种情况都不是问题。

接口分析

订单操作可分为读写操作:

  • 写操作:下单、确定订单、取消订单、其他订单状态变更。
  • 读操作:单个读、批量读。在写操作中伴随着订单读接口调用。

读写操作都需要做适配。

迁移流程

通过上节分析,整体过程如下:

  1. 【数据预热】按用户pin打开迁移开关,迁移job(迁移job在同步器模块中)开始迁移,以此同时,同步器开始接收接收并解析binlog日志,异步同步老库订单状态。
  2. 经过全量迁移后保证总数总数和已迁移订单大概在99%时,说明订单数据已经基本同步。这时打开灰度开关、双读开关和状态开关,此时下单流量到新系统,新订单在新系统生成。
  3. 在路由开关打开后,用户pin下的订单可能来自两部分:新系统 or 老系统,为了保证订单查询接口的正确性,存在一个短暂的双读过程。由于路由开关打开后老库订单是一定的,经过几轮全量同步和增量同步,数据可以达到新老系统一直。当两边一致时(订单数一致、订单状态99%几乎完全一致),此时将双读开关设置为完成。(双读过程很短暂)所有读请求走新系统。
  4. 对老库订单的确认、取消或其他写操作根据订单状态开关判断,当订单状态开关开启时,老库订单状态的变更还是走老库,同步器读取binlog,当发现有老库订单已确认、已取消或已完成时,说明这个订单声明周期已经结束,此时将订单状态开关设置为完成。所有写操作走新系统。
  5. 订单同步任务发现双读开关已完成 且 用户pin下所有订单状态开关已完成,此时更新灰度开关完成,所有读写请求通通走新系统。
  6. 下线老系统、下线新系统适配代码、回收资源。

关键设计

迁移组件

参考对象迁移,如下图所示

d7b35266c8bddbdcc1b4b6ebb0b5a0d8.png
  • 配置中心:存储迁移开关、灰度路由开关、双读开关和状态开关,并提供读写服务。
  • 控制中心:共开发和运维人员使用,可人工控制迁移状态(比如迁移暂停等等)、查看当前迁移进度(提供工具或页面进行查询)。
  • 适配代码:从上面的分析老新集群都要做代码适配。
  • 同步器:完成订单数据同步,新老订单系统字段映射、数据同步

开关设计

8fc9d8692cd619d46bc516a72757de85.png

The end.

转载请注明来源,否则严禁转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值