<返回更多

从MongoDB到PostgreSQL:数据零丢失、成本砍半

2024-05-15  dbaplus社群  
加入收藏

Infisical 是一家开源的密钥管理平台,为团队及基础设施提供同步密钥的服务并防止密钥泄露。随着业务不断发展、数据不断增加,原有数据库已无法满足当前需求,Infisical 决定从 MongoDB 迁移到 PostgreSQL 。本文将分享这一从非关系型数据库迁移至关系型数据库的决策判断及背后的迁移故事。

Infisical 在过去一年里迅速扩张,目前平台每天处理超过 5000 万个密钥,向需要数据的团队、CI/CD 管道以及服务器/应用程序,发送应用程序配置和机密数据。

随着使用量不断增加,我们必须持续升级技术栈。最近,Infisical 进行了从MongoDB到PostgreSQL的数据库全面迁移。此次迁移涉及到对方案的审慎评估、采纳新技术、创建新的数据库模式(schema)、重构逻辑、重写查询语句,将数百万(如果不是数十亿)的数据库记录迁移到 PostgreSQL。这过程十分复杂,但也是改善平台的必要一步。

本文将介绍我们从 MongoDB 迁移到 PostgreSQL 决策背后的故事以及迁移过程。希望这篇文章令人感兴趣,并为其他考虑进行类似数据库迁移的人提供帮助。

从何开始

最初构建 Infisical 时,我们选择了团队最熟悉的技术栈进行构建。作为这个方案中的一部分,我们选择了 MongoDB + Mongoose ORM, 因为这种组合的开销最小,并提供了快速交付高质量的功能。

正如托尼·霍尔爵士所说,“过早优化是万恶之源”,也确实没有进一步优化的必要,我们当时还专注于构建 Infisical Cloud(托管 SaSS 产品)。同时由于这一产品侧重点,我们并没有预计到有很多用户自行托管产品,所以也没有对这一用例设计相关方案。

为什么放弃 MongoDB?

虽然 MongoDB 在早期为 Infisical 提供了良好服务,但当我们产品场景发展到超出托管服务范围时,它开始显示出不足。随时间推移,我们发现许多组织,尤其是在合规性和安全性的交叉领域运营的组织,相较使用Infisical Cloud,更喜欢自托管 Infisical;同时用户也有些需要满足的本地需求。

随着对自托管 Infisical 的需求不断增长,我们发现已经开发了相当多功能来减少自托管 Infisical 所需的学习曲线,而在这一趋势的影响下,我们最终放弃了 MongoDB,转而使用 PostgreSQL。

在实践中,我们和我们的客户经常在功能和可用性方面受到 MongoDB 的限制,例如缺乏对 事务、清理的支持、云厂商托管产品的版本控制不一致,更不用说无模式(schema-less)数据库设计结构等相关问题。

下面详细阐述其中的一些挑战:

除了以上及其他原因之外,我们还意识到,将完整的数据库迁移到更通用的东西是让世界各地的团队和组织更容易使用 Infisical 所需的最终功能。

选择 PostgreSQL 的原因?

在寻找新数据库时,我们先列出最看重的几个方面:易于管理(即包括配置、部署和扩展)、内置事务支持以及关系型功能。我们还考虑了是否应该构建自己的集成存储或寻求外部存储解决方案。

以下是备选方案:

经过慎重考虑,我们选择了PostgreSQL。除了拥有充满活力的社区、广泛的文档以及众多可用的解决方案和扩展之外,我们最欣赏它的开源特性和绝大多数云提供商都支持 PostgreSQL 托管服务。

最重要的是,这意味着 Infisical 的用户可以更轻松地在任何云提供商上自行托管我们的平台,并将其与相应的托管 PostgreSQL 服务配对。此外,鉴于 PostgreSQL 已得到广泛采用,我们相信用户在使用 Infisical 时操作会更加便捷。

如何处理 ORM?

选择 PostgreSQL 后,我们需要弄清楚应用程序如何与数据库交互。我们第一反应是找到一些与使用 Mongoose ORM 的 MongoDB 体验类似的工具。因此,我们开始根据成熟度、可视化和迁移支持以及适当的抽象级别来评估候选工具;我们主要考虑了 Drizzle ORM、 Prisma ORM、 TypeORM和 Knex.js (一种查询构建器)。

最后,我们决定使用 Knex.js而非 ORM ,以便更好地控制数据库。无可否认的是,原始 SQL 是最通用的且抽象最少,但我们认为这种方法太容易出错,而且坦白说,在没有适当的TypeScript 支持的情况下,维护起来很麻烦。

此外,除了接近裸露的 SQL 之外,Knex.js 还自带用于播种和迁移工具包,拥有成熟的生态系统,其中包含出色的文档和几乎任何可能查询的答案。再加上一些定制的 Zod 集成工作,我们尽力使其对 TypeScript 的支持达到了令人满意的水平。

在决定了数据库和 ORM 后,我们启动了一个流程,最终导致整个应用程序重写数十个数据结构和数百个查询。

我们如何计划迁移?

代码重写即将结束之时,我们开始考虑如何进行迁移操作,将 MongoDB 数据映射到 PostgreSQL,同时将对 Infisical 云平台的干扰降至最低。

鉴于 Infisical 在客户基础设施中的关键作用,我们立即排除了绝对停机方案的可能性。我们不得不妥协的是,在短暂的迁移窗口期间禁止写入操作(即客户将无法创建或更新应用程序配置),以换取更高的数据完整性保证。这种权衡似乎可以接受,因为客户主要从 Infisical 获取机密信息,并且他们每秒更新其应用程序配置的可能性较少。

接下来,关于实际的迁移操作,我们需要从 MongoDB 转储数据、仔细转换,然后将其插入回 PostgreSQL。在审核迁移顺序时,我们克服了一些挑战,例如确保 NoSQL 中的各种树状结构正确转换为其关系对应结构;这对于具有递归考虑的文件夹等数据结构尤其敏感。

我们还发现需要一种持久的方式来存储 MongoDB 中的标识符并将其映射到 PostgreSQL 中的标识符;考虑到处理的数据量之庞大,在内存中这样操作是行不通的。最后,我们决定使用 LevelDB 键值存储来协助标识符存储和查找操作,将数据逐表移动到 PostgreSQL 中。

迁移

最后,我们准备好进行迁移。此时,没有直接参与代码库重写的人员用了一个季度的时间来改进 Infisical 的其他方面,包括进行前端更改、执行维护补丁、扩展客户端功能以及编写更好的文档。此时,所有人重新聚集起来,为迁移这一过程做准备——把应用程序代码库替换为新代码库,并将数据从 MongoDB 传输到 PostgreSQL。

作为准备工作的一部分,我们起草了一份详细的迁移清单以及预期时间表。

计划大体如下:

准备好计划,我们就着手执行了。

迁移效果

幸运的是,迁移执行顺利,数据零丢失,仅有一些非必要功能出现故障;我们在随后的36 小时内解决了这些问题,将对客户的影响降到最低。

迁移后,我们观察到了许多好处:

总体而言,考虑到当前的目标、任务范围及执行效果,我们认为此次迁移非常成功。我们打算在今后获得更多数据后公布更具体的结果。

结论

从 MongoDB 迁移到 PostgreSQL 从开始就不是一个容易的决定。总而言之,我们花了 3 到 4 个月的时间来执行该计划,并围绕为什么这样做、如何做等问题进行仔细规划和讨论,然后小心翼翼地执行这一切。

对于阅读本文的任何人,我强烈建议在尝试这样一项大型工作之前,深入思考用例和实施方案。总之,我非常高兴一切都按计划进行,我们能够提供如此巨大的更新,这将为 Infisical 用户带来巨大的变化。

非常感谢 Akhil Mohan 对迁移工作的大力支持,以及Infisical 公司其他所有人对迁移过程的协助。

作者丨Tony Dang 编译丨onehunnit

来源丨infisical.com/blog/postgresql-migration-technical

关键词:MongoDB      点击(4)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多MongoDB相关>>>