不久前我经历了一次数据迁移项目。前几天,我跟一位架构师探讨了一下当时的各个步骤,和我所选择并进一步开发的解决方案。我觉得我应该告诉他一些信息 ,避免他日后迁移数据时踩坑。
在我们的交流中 ,我提到了数据迁移的各种难题和我们遇到的问题。现在我意识到,这些东西对许多从事数据迁移项目的人来说都很有用。这些是很常见的问题,多是那些开始数字化转型的公司容易遇到的。数据迁移项目通常是一套解决方案,让你提取、转换旧数据,然后将其存储到新的系统中。
之前没想到的是,我从事软件工作以来只参与过一个数据迁移项目。感觉好像回到了我在学习 SQL 时挣扎的日子。那时的经历很有意思,你在 Oracle 和 MariaDB 上都使用 PL/ SQL ,并为此头痛不已。你只能自行猜测哪个是旧系统,哪个是光芒万丈的新系统。但今天不讲这个,今天讲我认为导致延迟交付的最大陷阱。这些大家可能都会遇到。
用 SQL 脚本做主要工具
这是昨天早上我忘了向同事强调的一个问题,今天早上它又在我脑海闪现。别误会,SQL 是强大的数据检索和查询工具。但是,当你有一个由多个开发人员组成的团队,并在同一个代码库上工作时,关键要确保你的更改能与其他代码很好地整合。
问题在于,要验证不同的场景时 ,我们不能只花几秒钟或几分钟运行典型的单元测试。我们必须执行实际的迁移,因此我不会称之为“集成测试”,因为集成测试的环境与实际环境有所不同(稍后将详细介绍)。
我们必须启动docker镜像,然后给将来要用真实数据应对的每种场景加载模拟数据。我们的Jenkins构建一次要 2-3 个小时才能完成。这使本地开发更加困难,因为没有人愿意花 5 分钟内改代码然后花 2-3 个小时来测试。最开始我们改为只运行我们需要的那些测试用例。那时 CI 非常慢,虽然最终我们将时间降到了 40 分钟,但仍然很慢,但考虑到我们正在处理的内容,可能这就是我们最好的选择了。
一些跟我讨论过的架构师,他们在那个项目期间,甚至项目结束之后都向我建议,用一种实际的编程语言可以使我们免于这种痛苦:你可以测试任意组件,完整的检索 、转换和加载操作只需几秒钟就够了。然后你再对理想路径进行一次集成测试。我们本来可以把 CI 构建控制在一分钟之内的,从而节省很多时间。
源字段和目标字段对不上
字段不匹配是很痛的痛点。我不是指从源数据字段到目标数据字段的对应错误,而是指字段对应没问题,但目标字段类型不对。由于数据的敏感性,我们研究解决方案时接触不到真实数据。
所以这种问题只有到了在生产环境运行时才会暴露出来。你可能会有一些源字段是字符串类型的,但目标字段却是整型的。当所有测试数据都是数值时不会有问题,但当在几百万实体中出现哪怕一两条包含字母时,就全都完了。还有些时候数据会被截断,因为目标字段所能表达的值范围比源字段要小。这种问题不是数据迁移工程的责任,因为目标系统不是我们设计的,但实际上我们在交付数据迁移方案时却不得不去修复这种问题。是的,现实并没有那么理想。
所以在这里我要强调的是,如果你要构建一个系统的新版本,请确保新的数据库字段的类型和格式都能匹配兼容源数据。我们不能截断地址或电话号码,尤其是当我们系统需要这些信息时。
与其他团队边界不明确
当时,我的团队是做数据迁移的。我们设计了一个解决方案,把数据从这里迁移到那里。但如上文所述,我们有时不得不修复目标数据库的问题,这些问题都是其他团队为各种功能折腾出来的。最重要的是,我不明白我的团队怎么就变成了其他团队的测试数据提供者。反正这些团队不会把所有的测试数据汇总在一起以便测试其功能,而是会来找我们为他们生成随机的测试数据。
回想起来,这么做真蠢。因此,我们构建的测试框架中有一个类用于生成数据。在开发时,我们把这些数据存到源数据库里,然后运行迁移过程,提取、转换这些数据,并把它们存到目标数据库里。接着再从目标系统中导出这些数据发送给那些团队。我认为我们做的太多了。我们应该把底线控制在“请您自行创建测试数据”上。
虽然帮助他人也是可以的,但我们不能在自己本职工作都没做完的情况下这么做。最后的结果就是,我们负责了整个工程的三个主要部分:数据迁移、修复目标数据库的问题、给每个人生成测试数据。
不同环境的设置
我记得当时我没有过多考虑各种部署环境的不同配置。从开发环境到预发布环境,再到生产环境,它们会有很多差异。显然,我们为此付出了代价。你可能会认为不同版本间的Oracle 数据库或 MariaDB 数据库应该不会有什么大问题吧?但如果我告诉你下个版本跟这个版本的差异会破坏掉你所有的 SQL 脚本呢?就像必须把 VALUES 替换成 VALUE。
想象一下迁移工具在你本地运行得好好的,接下来你把它推送到一个缓慢的 CI 过程。然后你再把它发布到一个环境,运行迁移过程并检查,没什么问题。结果到生产环境出问题了,因为生产环境的 MariaDB 版本太旧。此外,生产环境还是个 EC2 实例,而预发布环境则是 RDS。
这个项目在开发环境和在生产环境的变量设置完全一致,但我还是被它们输出的差异惊到了。为了在不同集成环境里都能起作用而到处改代码 ,要避免这种痛苦一定确保环境配置一致。你的解决方案预想可以在生产环境起作用,但其实它跟真实的生产环境配置一点也不像,这肯定就会出问题 。这绝对是我在这次经历中得到的最大一笔经验。
总结
我将在后面继续学习从旧项目获得的经验教训。我甚至会重温这篇文章来确保我不会忘记这些经验教训,因为它们在我下次进行数据迁移时还是非常有用的。更妙的是,其中一些经验教训不仅仅可以用于数据迁移,还可以应用于其他方面。
即使这次我没有去找个工具来做,本文谈到的这些经验也让我坚信应该找个好工具来做好工作。信任已有信息固然很好,但也不妨去看看周围,对自己也没有什么坏处。有时这些工具并不比 SQL 查询慢。
其次,尽可能确保开发环境的配置与生产环境一致。这将避免许多集成问题。
最后,当职责明确了之后,应避免给自己揽更多的活儿,它们会妨碍你的本职工作。
译自文章 《Data migration gotchas and lessons learned》