Firestore JOIN 陷阱

你面临一个常见的 Firestore 问题。你的 Firebase 函数抛出了最大批处理大小(maximum batch size)错误。你需要为仪表板关联(join)订单和客户数据。通常你会通过复制数据来解决这个问题。但现在你的数据变得陈旧且不一致。

Google 发布了 Pipelines API 来解决这个问题。它允许跨集合进行 JOIN 操作,而无需复制数据。一些开发者在小型测试中报告了极快的查询速度。

我花了一周时间在高负载下测试这个 API。以下是文档中没有告诉你的内容。

  1. 高昂的成本 每次 pipeline 执行都会从所有涉及的集合中读取数据。两个集合之间的 JOIN 会对两个集合的读取量进行计费。如果你对两个各包含 50,000 个文档的集合进行 JOIN,你的成本扩展性会很差。这并不是简单的线性成本。

  2. 性能限制 在我的测试中,针对 10,000 个文档的 pipeline 耗时 380ms。当我测试 100,000 个文档时,查询在 30 秒时超时了。你并没有解决问题,你只是把批处理错误变成了超时错误。

  3. 冷启动问题 Pipelines 会创建一个独立的执行上下文。在 Cloud Functions 等无服务器(serverless)环境中,这会增加 2 到 4 秒的延迟。你的用户会觉得你的应用很慢。

Pipelines API 是一个用于原型设计或处理 5,000 个文档以下小型集合的工具。它不是关系型数据库的替代品。Google 提供这个功能是为了帮助你留在 Firebase 生态系统中,而不是迁移到 PostgreSQL 或 Spanner。

如果你使用 Pipelines,请遵循以下规则:

• 审计你的集合大小。如果一个集合超过 20,000 个文档,请先计算 JOIN 成本。 • 限制复杂度。跨三个或更多集合进行 JOIN 是一个危险信号。 • 每周追踪读取成本。Pipeline 的读取在账单上的显示方式有所不同。 • 保留你的反规范化(denormalized)数据。将 Pipelines 作为补充,而不是完全替代。 • 使用真实流量进行测试。在安静集合上的基准测试并不能反映生产环境的真实情况。

不要试图用“创可贴”来逃避真正的架构决策。

你在 Firestore 中如何处理关系?你是使用反规范化还是客户端 JOIN?在评论区告诉我。

Source: https://dev.to/xu_xu_b2179aa8fc958d531d1/the-firestore-join-trap-what-googles-new-pipelines-api-costs-you-that-nobodys-talking-about-an7