我们公司花了半年时间,把数据中台从旧系统迁移到了新系统。整个过程踩了很多坑,也积累了不少经验。本文是这次迁移的实战总结,包括迁移背景、方案设计、执行步骤、遇到的问题、解决方案、以及最终效果。如果你也在做数据中台迁移,或者打算做,希望这篇文章能帮你少走弯路。

一、迁移背景

先说说为什么要迁移。

我们的数据中台是三年前建的,用的是当时比较流行的技术栈。Hadoop做存储,Hive做数仓,Spark做计算,用Airflow做调度。这套架构在当时是够用的,但是随着业务增长,问题越来越多。

第一个问题是性能跟不上。数据量从原来的TB级增长到了PB级,Hive的查询越来越慢,一个简单的查询可能要跑几个小时。Spark任务也经常因为资源不足而失败。

第二个问题是运维成本高。Hadoop集群的运维很复杂,需要专门的运维团队。而且组件多,版本兼容性问题经常出现,升级一次要折腾很久。

第三个问题是实时能力不足。旧系统主要是批处理,T+1的数据延迟已经不能满足业务需求了。业务方希望能看到实时的数据,比如实时的销售数据、实时的用户行为数据。

第四个问题是技术栈老旧。旧系统用的很多技术已经停止维护了,社区也不活跃了。继续用下去,以后招人、维护、升级都会越来越困难。

基于这些原因,公司决定建设新的数据中台,把旧系统的数据和任务逐步迁移过去。新系统用的是云原生架构,存储用对象存储,计算用Spark和Flink,调度用DolphinScheduler,同时支持批处理和流处理。

二、迁移方案设计

迁移方案的设计是整个项目最关键的部分。方案设计得好,执行就顺利;方案设计得不好,后面会踩很多坑。

我们的迁移原则是:不影响业务、逐步迁移、可回滚、可验证

不影响业务:迁移过程中,旧系统继续运行,业务方无感知。等新系统稳定运行一段时间后,再切流量。

逐步迁移:不是一次性全部迁移,而是按照业务域或者数据重要性,分批次迁移。先迁非核心的,再迁核心的。

可回滚:每个阶段都要有回滚方案,如果新系统出问题,可以快速切回旧系统。

可验证:迁移之后,要对数据进行校验,确保新系统的数据和旧系统一致。

具体的迁移步骤分为五个阶段:

  1. 基础设施搭建:搭建新系统的集群,配置好存储、计算、调度等组件。
  2. 数据迁移:把旧系统的数据同步到新系统,包括历史数据和增量数据。
  3. 任务迁移:把旧系统的计算任务迁移到新系统,重新开发和配置。
  4. 双跑验证:新旧系统同时运行,对比数据结果,确保一致。
  5. 切流和下线:把业务流量切到新系统,观察一段时间后,下线旧系统。

三、基础设施搭建

第一步是搭建新系统的基础设施。

我们的新系统部署在云上,用的是云厂商的托管服务,这样可以减少运维成本。存储用对象存储,计算用托管的Spark和Flink集群,调度用DolphinScheduler,元数据用Atlas,数据质量用Great Expectations。

搭建的过程中,我们踩了一个坑:网络配置。新系统和旧系统不在同一个网络区域,数据同步的时候网络延迟很高,速度很慢。后来我们打通了专线,才解决了这个问题。

还有一个坑是权限管理。新系统的权限模型和旧系统不一样,迁移的时候要重新配置权限。我们花了不少时间梳理权限,确保每个用户和任务都有正确的权限。

基础设施搭建好之后,我们做了一次性能测试,确保新系统的性能能够满足业务需求。测试结果显示,新系统的查询速度比旧系统快了5到10倍,计算任务的执行时间也缩短了很多。

四、数据迁移

数据迁移是整个项目中工作量最大的部分。

我们的数据分为两部分:历史数据和增量数据。

历史数据迁移

历史数据量很大,有PB级。我们用的是离线批量同步的方式,把旧系统HDFS上的数据导出到对象存储。因为数据量大,我们用了分布式同步工具,多线程并行传输。

历史数据迁移花了大概一个月的时间。中间遇到了几个问题:

  1. 数据格式不一致:旧系统的数据格式有CSV、JSON、Parquet等多种格式,新系统统一用Parquet。我们在迁移的时候做了格式转换。
  2. 数据压缩:旧系统的数据用了不同的压缩算法,迁移的时候要解压再压缩,比较耗时。
  3. 小文件问题:旧系统有大量的小文件,迁移的时候做了合并,减少小文件数量。

增量数据迁移

历史数据迁移完成之后,需要同步增量数据。我们用的是双写的方式,新数据同时写入旧系统和新系统,确保两边的数据一致。

双写用的是CDC(Change Data Capture)工具,监听旧系统数据库的变更,实时同步到新系统。这样可以保证增量数据的实时同步,延迟在秒级。

增量同步运行了一段时间之后,我们确认两边的数据是一致的,就进入了下一步。

五、任务迁移

数据迁移完成之后,开始迁移计算任务。

我们旧系统有几百个计算任务,包括数据清洗、指标计算、报表生成等。这些任务用Hive SQL和Spark开发,用Airflow调度。

任务迁移不是简单的复制粘贴,因为新系统的技术栈不一样,很多任务需要重新开发和优化。

我们的迁移策略是:

  1. 按业务域分组:把任务按照业务域分组,每个业务域安排一个负责人。
  2. 先易后难:先迁简单的、独立的任务,再迁复杂的、有依赖的任务。
  3. 重新优化:利用新系统的特性,对任务进行优化,比如用向量化查询、动态分区等。

任务迁移过程中,我们遇到了几个典型问题:

问题1:SQL语法不兼容

旧系统用的是Hive SQL,新系统用的是Spark SQL,两者的语法有一些差异。比如某些函数的用法不一样,某些配置项的名字不一样。

解决方案:我们写了一个SQL转换工具,自动把Hive SQL转换成Spark SQL,然后人工审核和调整。大部分SQL可以自动转换,少数复杂的需要手动改写。

问题2:UDF不兼容

旧系统有很多自定义函数(UDF),是用Java写的,依赖了旧系统的一些库。新系统的运行环境不一样,这些UDF不能直接用。

解决方案:我们把UDF重新编译,适配新系统的运行环境。对于一些性能不好的UDF,我们用Spark内置的函数重新实现。

问题3:任务依赖复杂

旧系统的任务之间有复杂的依赖关系,Airflow的DAG定义也比较混乱。迁移的时候,经常出现依赖遗漏或者错误的情况。

解决方案:我们重新梳理了任务依赖关系,画了依赖图,然后在新系统中重新配置。同时制定了规范,要求每个任务都要有清晰的依赖说明。

六、双跑验证

任务迁移完成之后,进入了双跑验证阶段。

双跑验证就是新旧系统同时运行相同的任务,然后对比两边的结果,确保数据一致。这是迁移过程中非常重要的一步,也是最容易发现问题的一步。

我们的验证方法是:

  1. 每天同时运行新旧系统的任务。
  2. 任务完成后,自动对比两边的数据结果,包括数据量、字段值、聚合指标等。
  3. 如果发现不一致,生成差异报告,人工排查原因。

双跑验证跑了大概一个月,发现了不少问题:

问题1:时区不一致

旧系统用的是UTC时间,新系统用的是北京时间。导致按天统计的数据差了一天。

解决方案:统一时区,全部用北京时间。在数据导入的时候做时区转换。

问题2:空值处理不一致

旧系统中,空字符串和NULL是混着用的。新系统中,我们统一用NULL。导致某些统计结果不一致。

解决方案:在数据清洗的时候,把空字符串统一转换成NULL,确保两边的处理逻辑一致。

问题3:精度丢失

旧系统用的是double类型,新系统用的是decimal类型。某些金额计算的结果有微小的差异。

解决方案:统一用decimal类型,保留足够的精度,避免精度丢失。

问题4:去重逻辑不一致

旧系统的去重逻辑是先排序再取第一条,新系统的去重逻辑是用row_number。在某些边界情况下,结果不一样。

解决方案:统一去重逻辑,确保两边的算法一致。

这些问题看起来都是小问题,但是如果不发现,上线之后就会导致数据错误,影响业务决策。所以双跑验证是非常必要的。

七、切流和下线

双跑验证通过之后,开始切流。

切流不是一次性全部切,而是逐步切。先切10%的流量到新系统,观察一天,没问题再切30%,再切50%,最后全部切过去。

切流的过程中,我们密切监控新系统的性能和数据质量。如果发现问题,立即切回旧系统。

切流完成之后,我们又观察了两周,确认新系统稳定运行,没有问题,才开始下线旧系统。

下线旧系统的时候,也不是直接关掉,而是先停掉任务,保留数据一段时间,确认没有问题之后,再释放资源。

整个切流和下线过程比较顺利,没有出现大的问题。这得益于之前充分的准备和验证。

八、迁移效果

迁移完成之后,我们做了一次效果评估。

性能提升:查询速度平均提升了6倍,计算任务执行时间平均缩短了50%。以前要跑几个小时的任务,现在几十分钟就能跑完。

实时能力:新系统支持实时计算,数据延迟从T+1降到了分钟级。业务方可以看到实时的数据,决策更及时了。

运维成本:新系统用的是云托管服务,运维成本降低了60%。以前需要一个团队运维Hadoop集群,现在只需要一个人兼职管理。

扩展性:新系统的扩展性更好,资源可以按需弹性伸缩。业务高峰期自动扩容,低谷期自动缩容,成本降低了30%。

数据质量:新系统引入了数据质量监控,数据错误率降低了80%。业务方对数据的信任度提高了。

总的来说,这次迁移是成功的。虽然过程中踩了很多坑,但是最终达到了预期的效果。

九、经验总结

最后总结一下这次迁移的经验。

1. 方案设计要充分

迁移之前,一定要花足够的时间做方案设计。把可能遇到的问题都想清楚,制定详细的计划和回滚方案。方案设计得越充分,执行就越顺利。

2. 数据校验是关键

迁移过程中,数据校验是最重要的环节。一定要有完善的校验机制,确保新系统的数据和旧系统一致。数据不一致,迁移就没有意义。

3. 逐步迁移,不要一刀切

不要想着一次性全部迁移完。分批次、分阶段迁移,每一步都验证通过之后再进行下一步。这样风险可控,出了问题也容易定位。

4. 业务方要参与

迁移不只是技术团队的事情,业务方也要参与。让业务方了解迁移的进度和影响,配合做数据验证和测试。业务方的参与,能让迁移更顺利。

5. 文档要完善

迁移过程中,要做好文档记录。包括迁移方案、执行步骤、问题记录、解决方案等。这些文档不仅对当前项目有用,对以后的维护也很有价值。

6. 预留足够的时间

迁移项目往往比预期的要花更多时间。我们原计划四个月完成,实际花了半年。所以在做计划的时候,要预留足够的缓冲时间,不要把时间排得太满。

十、写在最后

数据中台迁移是一个复杂的系统工程,涉及到数据、任务、调度、权限等方方面面。整个过程需要耐心和细心,不能急于求成。

我们这次迁移花了半年时间,踩了很多坑,但是也收获了很多。新系统上线之后,性能、稳定性、扩展性都有了很大的提升,为业务的发展提供了更好的数据支撑。

如果你也在做数据中台迁移,希望我的这些经验能帮到你。记住,迁移不是目的,提升数据能力才是目的。不要为了迁移而迁移,要想清楚迁移能带来什么价值。

最后用一句话结束本文:"迁移是手段,不是目的。以终为始,方能行稳致远。"愿每一个做数据迁移的团队,都能顺利完成迁移,实现数据能力的提升。