非常幸运,这几年系统迁移的事情基本被我赶上了,从外部系统迁移到内部系统迁移,从小项目到大项目都实践过。迁移中踩过的坑和自我的总结,在这里给大家分享分享。
随着业务的发展,原有系统支撑当前业务就显得力不从心了,这时就考虑进行系统拆分或者内部升级了,拆分成另外一个微服务或者内部模型升级,这里将拆分的过程或者升级的过程统称为迁移,那么新老系统业务过度期间如何保证系统平稳的对接呢?
根据数据特点迁移可分为两种,数据迁移和系统迁移
数据迁移
数据迁移适用于系统间的变动只需要通过数据的迁移就可以解决的场景,比如分库分表的时候数据迁移,在迁移过程中可以通过迁移前后的数据对比来保证数据的完整性,如迁移的时候分批处理,每一批数据迁移完成后进行总量的对比,保证数据完整迁移过去。
数据迁移数据属于比较简单的迁移方式,通常由DBA进行,开发投入量不大。
系统迁移
这种情况就得根据业务情况来分析了,一个系统的业务可以有多复杂就有多复杂,需要花费大量的时间保障迁移的正确与完整性。
根据系统拆分的方式和迁移的方向,系统迁移又可以细分成外部系统迁移和系统内部迁移,无论是内部迁移还是外部迁移,总体流程基本一致。
迁移考虑点
在初始业务情况下,多个领域功能业务都冗余在一个系统中,如果需要对某个领域模块迁出形成新的一个系统服务,这种可以称为新增系统迁移,那么如何保证系统的平稳迁移呢?迁移都可以从以下几个点考虑
- 新系统的稳定性
这个得要根据公司的具体基础组件功能来说了,如果是公司有成熟的服务组件,新增系统只是简单的一个容器的部署的话,这个问题的优先度可以放到最低考虑。如果没有成熟的组件,新系统意味着重新搭建一套服务体系,那么这时系统的稳定性就得优先考虑了。如何保证系统不挂掉?如何保证就算系统挂掉一部分也不影响整体业务?如何快速止损?这些问题就显得尤为重要,得要优先考虑了。
- 业务重要性
这是一个很现实的问题,如果一个业务的重要程度不高,或者出问题基本没什么影响,那么这个业务迁移的时候可以放心大胆的迁,否则都要非常小心的处理系统迁移过程
- 灰度
系统迁移过程中,如何进行灰度验证呢?一开始总不可能把所有的量都放开,都是从小量到大量的处理,灰度可以有助于提前发现问题
- 限流
根据业务规则进行速度限制,大量的请求瞬间过来对业务的影响是非常大的,这里可以使用令牌桶的方式进行限速。限速的过程会调整非常频繁,这里就需要使用的到分布式配置了。如果系统中没有这类组件,可以通过DB或者缓存的方式调整速率。
- 降级
这个和限流有着类似的情况,设计的时候需要考虑如何对此功能进行降级,如新增的系统有问题,仅仅通过限速是不能解决问题的,还需要降级的方案。
当新系统稳定性无法保证的时候,对迁移的业务可以添加一个兜底的逻辑,不对原有的业务进行修改,如果新系统处理失败则进行原有逻辑执行
- 监控
这个就不必多说了把,要掌控系统的稳定性,必须要有对应的监控,否则就成了瞎子一样,生产事故只能通过用户反馈。
监控还可以通过T+H离线DB数据比对,和实时数据比对,比如数据发生变动后,核对平台通过监听DB数据变动从而进行业务逻辑比对,从而达到数据实时比对功能。
- 告警
有了监控以后,当然需要配备对于的告警,否则监控做的再好放在那里没人看也起不到对应的作用,配合告警可以发挥出非常好的效果,不过这里得注意告警的配置,主要是告警的级别和次数,如果告警的东西多了,容易产生告警疲劳,当真正有事故发生的时候告警却被忽略过去。
- 回滚
迁移系统设计的时候就需要考虑好正向和逆向流程,没有回滚方案的迁移都是耍流氓,如果出了问题,不能回滚,对于数据量大的情况下,数据处理几乎是一场灾难
- 流量回放/流量对比
新系统迁移完成后,那么在测试阶段如何快速发现问题? 可以将历史访问流量进行回放,比如查询类的接口数据,模拟线上的访问,流量回放成功后那么流量对比就排上用场了,流量回放仅仅能解决业务数据的问题,但是最终结果的准确性则需要流量对比进行处理了,可以根据返回的数据进行对比,对比的时候需要主要返回业务的顺序,比如有些业务就是根据服务接口返回的数据进行展示,那么数据的显示顺序就显得尤为重要,对比的时候千万不能忽略。
系统迁移
系统内部迁移
内部迁移的情况往往是为了偿还技术债务,还有一部分情况是业务需求的变更,原有的模型已经不能满足现有的需求,但是迁移到新业务逻辑后还有一大批历史数据要处理,无法单纯的通过DB的数据变动达到迁移的效果,那么则需要进行内部迁移,内部迁移建议通过构造现有的接口数据进行业务处理。因为是内部系统迁移,不能对外部系统产生其他影响,简单的说就是其他系统是无感知的。
那么如何保证迁移过程顺利完成,迁移如何保证数据一致性?如何迁移?迁移的节奏?
镜像迁移
根据现数据将数据迁移到系统中,对请求流量进行复制,这样可以通过对比新老数据以及业务进行测试,但是这样成本高,而且得要把控好整个系统流程才可以,否则会出现消息重复发送,数据重复处理等问题。这种迁移方式适合那种查询为主的系统,而且对外处理流程较少,可以比较好控制。
预迁移
当镜像迁移不能满足时,我们可以通过预迁移的方式进行处理。
预迁移顾名思义就是在迁移前进行模拟迁移操作,比如可以把数据迁移到专门用来迁移的租户下面,并做好映射关系,查询老数据的时候异步进行新链路查询,然后对比返回的数据,从而达到提前验证的目的。
不过预迁移中需要特别注意数据同步,比如老数据修改了,需要实时同步到用来迁移的租户,而且得要更新好数据映射关系。
在查询老数据的接口上,进行流量复制并做转换成用来迁移的租户的请求数据,将返回的数据通过映射关系一一进行比对,这里比对可以使用反射或者json的方式进行对比,输出比对不一致的信息并告警。这里要特别注意下,所有流程必须要可控的。比如可以屏蔽某些数据不进行对比,某些意料中的对比失败数据可以忽略。需要做到这一点分布式配置中心就非常有必要了,如果当前系统还没有此功能,那么可以使用db或者缓存都可以,只要能达到实时变更配置数据都可以。
同镜像迁移类似,不过这里不需要新增一个系统,而是在原有系统中进行数据预迁移,不过这里是将业务逻辑模拟迁移过程,比如可以将数据迁移到新的租户下面,从而达到数据的隔离。
预迁移还有数据集的问题,在数据量大的时候,将数据迁移到专门用来迁移的租户下面可能系统无法支撑这么大的数据读取或操作,这时候需要提供多个迁移租户用来承载这些数据,当然如果系统可以做到一对一映射这是再好不过了。
预迁移的处理流程:
这里需要同迁移流程一样,允许有部分流程不一致,但是核心流程必须一致,否则预迁移工作做得再好,数据验证再完美也无法保证迁移的正确性。
预迁移持续的时间:
这个需要根据业务周期来定夺了,在预迁移过程中可以非常好的迁移过程中可能的问题,观察时间可以根据业务特点来,最好的方式是将一个业务的所有生命周期都走过一遍,然后前期检查好预迁移的数据情况,这样迁移基本十拿九稳了。
迁移
前面做了那么多工作,就是为了迁移这一步,完成迁移才是本质目的,在预迁移经过一段时间的验证后,可以开始少量的迁移工作,迁移的时候需要注意:
1 少量验证:一开始的时候需要非常小心,最好都是人工处理,每一步都进行数据验证,在迁移的时候如果有涉及到其他系统,还需要提前打好招呼,万一迁移有问题无法回滚,还需要地层帮助,临时找人可不是一个明智的决定。验证的过程中需要把所有核心流程都走一遍,比如订单相关的需要验证订单的正向流程,还要验证订单的逆向流程,还有金额数据等等,这些根据具体业务来定,核心思想就是正向,逆向流程必须要走通。
2 分批迁移:经过少量验证后,基本流程已经没问题了,这时候可以开始批量处理了,这里批量还是推荐分批较少数据。批量迁移开始的时候人工处理就显得力不从心了,自动化验证和核对这时就派上用场了,自动化验证可以通过查询核心接口,对比迁移前和迁移后的数据,在迁移前将数据采集下来保存,迁移完成后进行流量回放,流量回放可是一个技术活,如果系统接口没有时效性,那么可以直接将以前采集的数据进行回放。如果数据具有时效性,比如当前查询和一小时后查询的结果是不一样的,跟时间有相关性,那么这种数据采集就需要在迁移前实时处理了。
分批迁移的时候最好根据业务特点进行分块处理,比如数据跟地域相关的在迁移前优先迁移方便处理的地域数据,需要先联系好地域负责人。某一个地域迁移成功后可以逐步往其他地域迁移,一个重要点就是如果数据处理你不能百分百操作,那么一定要先联系好其他模块负责人!
3 大批量迁移:经过分批迁移后基本验证数据迁移的正确性,这时候可以开始大批量进行迁移了,这里推荐迁移的时候优先处理生效数据,有些数据没有生效,但是也需要迁移,这些可以放在后面进行,保证主体核心链路迁移完成
回滚
没有回滚方案的迁移都是耍流氓,如果迁移后发现数据问题无法处理的时候,这时候就需要回滚了,这里得要说明一个原则,回滚是不得已的办法,只有在其他方法都无法处理的时候才进行回滚。
回滚可不是一个简单的活儿,有一个非常重要的点,如何保证回滚后的数据和之前数据的一致性?数据核对如何处理?
这时数据备份就显得非常重要了,可以将新产生的数据全部删除,然后通过备份数据的id将历史数据恢复。
以上说的都是正常的回滚,没有增量数据的情况。如果迁移后数据有变动了,这时候回滚就得要根据最新的数据进行回滚,那么逆向流程的验证就非常重要了,如何保证数据的一致性,这个就和迁移的过程一样重要。
还有一种就是无法进行回滚,迁移后数据改变了,没法通过最新的数据映射到老数据,或者成本太高,那么有损回滚可以考虑下,通过还原备份的数据,在将新数据链路上做的操作在老链路上再做一次,保证数据的一致性。
迁移的感想
- 过程完全没有想象的那么简单
- 注意环境隔离,比如预发环境和线上环境数据问题,本来在预发的数据在线上执行是否会有其他问题,如果有需要控制好环境数据
- 数据重复迁移,在设计的时候需要考虑好是否可以重复迁移,比如系统以来其他系统,如果有任何一步失败了这时候是否允许通过再次迁移的方式来继续迁移。如果允许重复迁移,那么数据控制就得要非常细心了,比如数据已经发生了变化,再次迁移的话可能会导致数据被覆盖
- 完善工具:处理的时候最好是通过工具进行处理,比如提供一个h5页面进行操作,迁移的时候都是非常小心而且紧张的,越是傻瓜式的工具越能提供更好的保障
- 核对:可以通过迁移后新老数据进行核对,保证迁移后数据的正确性