服务之间的数据迁移:策略、风险与权衡
Source: Dev.to
Source: …
背景
最近我在一次任务中需要在两个服务之间迁移数万条审计记录!这是我第一次进行如此规模的数据迁移,我学到了很多东西,于是决定在本文中把所有经验记录下来。
基本上,数据迁移是指将一组存储在某个来源(比如数据库、电子表格或其他格式)中的信息,转换后能够被另一个服务正确消费,且符合目标端的模型和规则。

迁移动机
- 需要将遗留数据迁移到新服务。
- 不同系统开始共享职责,需要保持数据的一致交集。
- 预先规划,能够为分析和执行争取更多时间。
- 紧急需求,例如客户请求、某部门的需求或意外的运营需求。
迁移的决定可以来源于产品团队,也可以来源于工程团队。但工程团队有责任评估并最终确定迁移的技术可行性!这种可行性直接取决于我们对现有数据的研究。
例如,当需求来自产品时,工程通常会有更大的空间去调查复杂性、风险和成本。但这并不能仅凭一句“可以迁移,交给我吧”来解决。任何承诺之前,都必须非常重要地分析涉及数据的体量、结构和复杂度。

一个明显的例子:让一两个开发者停下来两次冲刺(两轮 Sprint)去迁移15 条记录值得吗?在大多数情况下,不值得。工程成本可能远高于对产品的微小影响。
当然,可行性不仅仅是数字。产品的背景同样重要。以下问题有助于决策:
- 正在迁移的是什么类型的数据?
- 数据是简单的还是递归的?
- 记录之间是否存在依赖关系?
- 是否有中间状态、历史记录或业务规则与这些数据耦合?
所有这些都会直接影响最终的决定。
迁移阶段
当迁移被认为是可行的时,需要解决的问题集合通常分为三个主要阶段:
- 提取 – 数据将如何被提取?
- 转换 – 这些数据将如何适配为预期的格式?
- 加载 – 转换后的数据将如何发送到目标服务?
正是在这种背景下,我了解了 ETL,这是一种专门用于组织和结构化此类过程的方法(恭喜,你也学会了 ETL 是什么! :))

尽管如此,仍需强调:ETL 不是万能药。在许多情况下,创建专门的迁移应用可能是多余的复杂性。在任何实现之前,必须研究迁移的实际可行性,了解源数据的格式、转换工作量以及维护该解决方案的成本。
一般来说,当迁移需要多次执行或在未来重复使用时,ETL 更有意义。对于一次性迁移,使用更简单的方案可能更足够且更安全。
策略
小型迁移
当我处理小型迁移时,通常会选择简单的方案。尤其是,我非常喜欢使用 Jupyter Notebook,特别是当源数据位于电子表格或小型数据库时。在这些场景下,我并不觉得有必要为了执行一次性过程而构建完整的应用程序。
创建 notebook 相对简单:只需一个后缀为 .ipynb 的文件以及本地配置好的 kernel。根据具体情况,可以使用 Kotlin、Python、Deno 等多种选项。其最大的优势在于能够快速探索数据、测试转换并且轻松迭代。

复杂迁移
对于更复杂的迁移,我更倾向于 创建一个本地运行的终端应用——一个简单但受控的 CLI。这种方式能够:
- 提供更高的可预见性和执行控制;
- 便于处理大规模数据;
- 支持版本管理和自动化(例如:CI/CD 脚本)。
典型的迁移 CLI 结构包括:
- 参数解析器 – 用于接收起始/结束日期、过滤条件、dry‑run 模式等参数。
- 抽取层 – 与数据库、API 或文件的连接器。
- 转换层 – 接收记录并返回目标格式的纯函数。
- 加载层 – 批量插入、写入文件或调用目标 API。
- 日志与指标 – 用于审计和监控迁移进度。
结论(第一)
- 在开始之前评估迁移的可行性至关重要——考虑数据量、复杂性、依赖关系和工程成本。
- ETL 是一个强大的工具,但只有在需要复用或定期执行时才应采用。
- 对于一次性的小规模迁移,Jupyter Notebook 或临时脚本更为灵活。
- 对于大规模或需要细粒度控制的迁移,CLI 或小型专用应用是更安全的选择。
[](https://media2.dev.to/dynamic/image/width=800,height=,fit=scale-down,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8w59uslh300rzxxop5e.png)
在这里,一个根本性的关注点是拥有回滚策略。绝不能假设迁移第一次就能完美运行。尽可能在预发布环境中进行测试,再在生产环境执行,并且要与团队充分协调 rollout。
数据加载方式也很重要。在某些情况下,直接写入数据库可能足够。其他情况下,使用 API 或甚至将事件发布到队列更安全,尤其是处理大批量数据并希望以异步方式处理时。
归根结底,ETL 的形式不如最终目标重要。它可以是 notebook、CLI 或甚至一个简单脚本——只要能够安全、可预期地完成抽取、转换和加载需求。
实际挑战
缺失或不一致的数据
在真实迁移中,常常会遇到不完整、不一致或标记为已删除(例如:软删除)的数据。这些情况需要明确处理,可以忽略记录、填充默认值或标记未知数据。
数据丰富
并非所有必要信息都在同一个地方。通常需要“对接”其他数据库或服务/API以获取缺失的数据。最好从一开始就关注这一点,因为它会增加解决方案的复杂性。
技术权衡
- 速度 vs 正确性 – 当迁移紧迫时,需要决定在不影响交付的前提下,能够接受数据不一致的程度。
- Jupyter Notebook vs CLI – 对于小规模迁移,Notebook 能快速解决问题并提升效率!但它可能会迅速膨胀,导致可读性和可维护性下降。此时,采用 CLI 更为合适。
- 全部迁移 vs 只迁移核心数据 – 并非所有数据都值得迁移。必须与产品团队对齐,明确哪些数据需要保留,哪些可以在知情的前提下舍弃。
- 一次性处理全部 vs 分批处理 – 推荐将记录分成 batches(批次)处理,并在每个批次后验证结果。这种方式远优于一次性处理全部数据,后者一旦出现小的处理错误就可能需要全部重做。
结论(第二)
如果没有人注意到数据迁移在生产环境中进行,这可能是个好兆头。归根结底,一切归结为 上下文、平衡和权衡 — 并且要让团队保持一致,了解可以交付的内容。