背景
学前启蒙教育赛道,竞争日益激励,好未来集团旗下“小猴英语”,“小猴语文”,”小猴思维“三条独立产品站线,战略调整,资源合并,重拳出击,打造全新”小猴启蒙“品牌,专为2-6岁学前儿童打造的启蒙课程。
现状
- 语言层面:小猴英语主技术栈使用JAVA语言; 小猴语文、思维主技术栈使用PHP语言
- 结构层面:数据依赖关系、类型差异化大,无法相互转换
- 存储层面:课程存储结构、课前、课外、课中存储结构差异化大
- 运营层面:独立运营、面向群体、策略方式均不相同
- 课程层面:课程差异化大,制作流程均不相同
方案
行业常见的迁移方案有“停机迁移”、”双写迁移“、”实时(单向)迁移“,每一种方案都各自的特点和优劣势,对各个方案进行分析。
- 停机迁移:主动型,迁移时机可控,复杂度较低,风险较低,成本低,对业务有损,对用户不友好
- 双写迁移:被动型,迁移时机可控,复杂度较高、风险较高,成本较高,对业务无损,对用户友好
- 实时迁移:被动型,迁移时机不可控,复杂度高,风险较高,成本中等,对业务无损,对用户友好
挑战
在集团战略背景推动下,结合当前现状及对未来规划,期望抛弃历史包袱,轻装上阵,综合考虑后采用实时迁移方案。面临诸多挑战,例如:
- 迁移时机:不可控,用户自主触发迁移
- 不可逆:一旦触发迁移,过程不可逆,应对突发情况,要有应急预案
- 一致性:数据一致性,迁移前和迁移后的数据不能丢失
- 给飞机换引擎:兼顾用户体验,尽可能确保整个迁移过程用户无感知,平滑过渡
迁移方案
小猴启蒙是一个全新的品牌,全新架构设计、存储结构设计,课程制作&排课设计,兼容旧的三科产品形态,同时具备灵活可扩展的能力。
第一步、迁移时机明确
迁移时机是用户下载小猴启蒙APP,登录之后触发时机,触发时机后首先通知三科服务,限制不可用,确保不会有新的数据长生,此时启动迁移脚本进行数据迁移,在此期间要确保迁移速度足够快并且确保数据一致性,从而提升用户体验,整个过程不可逆,一旦出现紧急情况,需要有应急预案,迁移成功之后,用户即可在小猴启蒙APP上课(英语、思维、语文)。再也不用在三个APP中上课
第二步、数据分析&归类
通过对业务及数据分析&归类、数据可分两大类基础数据、用户数据。两种数据类型特点也各不相同,例如:
- 基础数据:公有数据,其中包括售卖商品、积分商品、课包、绘本、儿歌
- 用户数据:个人隐私数据,其中包括权益、积分、报告、课内数据,经过细分发现用户数据可分为核心数据、交易数据,例如:
- 核心数据:权益、积分
- 交易数据:交易记录、上课、完课记录等明细数据
第三步、针对不同数据特点,制定适宜迁移方案
通过上述分析了解业务当前的数据及特点分析,例如:
- 基础数据:数据量少、基础前置数据,可控迁移时机及迁移时间,风险可控,可人工校验。
- 用户数据:这部分数据比较特殊,核心数据量较少且重要,明细数据量较大且重要程度没有核心数据的高,迁移整体复杂度较高,核心数据实时迁移,交易数据一旦发生就不会在有变更了,如果数据量大,可前置迁移,配合着用户触发迁移进行最终的数据迁移。迁移时机及时间不可控,用户触发,风险不可控。
第四步、”实时迁移“技术方案剖析
整个迁移架构设计思想”透明化、先于用户发现问题,分钟级解决,数据可回溯“。在用户触发迁移时机后,调度中心通过采用Invoke反射机制,启动迁移子任务&监控个子任务的状态(耗时、里程牌),子任务视数据量决定是否分片处理。
-
核心架构设计点:RDS-TO-DRDS:面对交易明细或学习记录这类数据,为了在迁移时提升查询速度,可以考虑将数据同步到DRDS中,按照用户ID做分库分表的主键
- 任务解耦:面对多个业务模块或任务数据上下依赖关系时,通过解耦的方式降低或减少上下依赖,例如:商品、订单、物流这几个模块,都是有层次关系的,常规流程肯定是先商品然后在订单之后根据订单生产物流数据,串行方式,这样带来的问题就是效率,故通过某种方式进行解耦,数据之间的依赖关系一般情况下依赖ID,这里我们可以保持某种情况下相同旧的ID生成的新ID要保持一致,另外在迁移的过程中除了有历史数据,还有新增数据,建议通过ID位数区分开来,避免撞针,另外也便于排查问题,根据ID即分辨出新的业务数据还是历史数据。
- 多任务并行:并行是为了提升迁移速度,这块没什么可说的。
- 可回溯:历史数据的关联主键ID是字符串类型的,需要相同旧的ID生成的新ID要保持一致,记录&存储下来,当然还有一种是根据ID通过算法生成,然后通过算法反推出来。
- 数据分片:数据分片也是为了提升迁移速度。
- 幂等性:为了保证因不可控因素导致中断或异常,保证数据的一致性所做的工作
- 隔离:首先保证用户与用户之间是隔离的,其次是任务是隔离的,为了保证稳定性
- 进度监控:为了能够对线上的情况了如指掌,每一个系统监控都是不可或缺的。
- 状态计算:多个子任务同时工作,需要通过调度中心计算最终的迁移状态,结果,耗时等。
- 调度中心:涉及所有各个业务模块的数据,故每个模块都称之为子任务,通过调度中心统一调度,监控,计算整体迁移进度;触发所有的迁移子任务&监控&计算。计算所有子任务的迁移状态计算最终的迁移进度,迁移耗时,迁移数据量,核心关键数据。
- 监控告警:为用户迁移内容,提供透明化的监控手段,先于用户发现问题
- 质量保障体系:为数据一致性提供的手段,及突发情况的预案。
- 数据分片Proxy:降低迁移耗时提升用户体验,解决大数据量迁移问题。
- 异构数据转换:从旧业务数据提供数据,经过格式转换、数据建模,结果计算,后置处理完成整个子任务的数据迁移;其中里程碑是记录核心关键步骤,目的是为了快速定位问题。
- 业务ID转换器:数据ID类型发生了变化,字符串变成数值类型,为了确保数据一致性,故所有数据都可回溯,便于追溯数据前生今世。
第五步、质量保障体系设计
为了提升用户体验及迁移的速度及数据一致性所做的工作,使出现突发情况,我们能够对突发情况有应急预案。
对各个模块(任务)状态&进度监控,配备了自动修复机制,处理一定程度上的问题,当自动修复机制处理不了时,及时的预警处理,我们通过补丁助手可以快速修复问题。
上线
上线是对我们前期所有的工作的一个考验及验证,这个过程我们还是要谨慎操作的。
内测阶段分为两步:
- 内测:内部测试+数据演练
- 外测:抽样不同类型的用户,作为种子用户进行测试。
- 自然阶段:这个阶段还是比较保守,求稳为主,逐步阶段。
- 建议阶段:相对来说已经一定的信心了,可以中等规模的通知迁移。
- 强制阶段:大规模的迁移阶段了
- 沉默阶段:对沉默用户做迁移了,这部分数据是最后一批用户数据了
复盘
在上线的每一个阶段,对每个问题都要进行复盘总结,避免同样的问题再次发生,当复盘之后会发现,出现的问题都很低级,不应该出现的问题。例如:
环境问题:刚刚开始在预发环境,后期上线后对某个数据库地址修改拉下了,导致数据迁移不是最新的
Redis问题:缓存过期时间没有控制好,导致飞速增长。
ID问题:两边事前沟通不清楚、导致数据对不上。
总结
数据模型建立的方法
- 深入了解两侧业务设计、数据结构设计
-
新旧映射关系整理(点对点转换)
- 根据新的数据结构设计反向推旧系统的数据结构设计
- 字段属性映射、关系映射
- 字段特殊类 型的含义
-
新结构新增的字段整理
- 新增字段的数据来源
- 新增字段的类型转换
-
新增数据结构整理
- 获取数据源前置条件
- 获取数据源方法
- 结果属性和新增数据结构映射
战绩
迁移数据量过20亿
未出现聚集性问题、失败率0.1‰
专利产出(已授权)数据迁移方法、装置、电子设备及存储介质
成长
对个人成长还是比较大的,在技术上,架构设计权衡各方利益关系,没有完美的架构,只有最适合的,不能只关注架构层面,对细节点及落地也需要更加的关注,细节决定成功。在项目管理上,对项目沟通协调、节奏、风险把控也有很大的提升,作为此次项目Owner,负责并协调七八种角色,将近30人,此次项目的成果离不开组内及各位伙伴的定力支持,另外也要感谢刘俊海老师对整体方案的指导。