Learn the "why" behind slow queries and how to fix them in our 2-Part Webinar.
Register now >
Docs 菜单
Docs 主页
/ /

为MongoDB Search 构建多租户架构

您可以使用MongoDB Search实现多租户,以便应用程序的单个实例为多个租户提供服务。本页介绍专门应用于MongoDB Search 的设计建议,用于结构化数据和MongoDB Search 索引,以便在保持租户隔离性的同时安全扩展。

重要

本指导假设您可以在单个 VPC中共置租户。如果需要严格的网络隔离性,则必须为每个租户维护单独的项目。

根据您的隔离性需求、扩展目标和写入负载要求选择策略。最常见的策略是:

  • 所有租户的单个集合- 建议对大多数工作负载使用此 策略。

  • 每个租户一个数据库 - 此策略提供高度隔离性,但会增加索引计数。

  • 每个租户一个集合 不建议对MongoDB搜索工作负载使用此策略。

我们建议应用“所有租户使用一个集合”策略。在此架构中,您将所有租户数据存储在单个数据库内的单个集合中。您可以通过在每个文档中包含tenant_id 字段来区分租户。此字段可以是租户的任何唯一标识符,例如 UUID 或租户名称。

这种集中式方法具有以下优点:

  • 减少索引数量

    由于所有租户数据都存储在一个集合中,因此您只需要一个为所有租户提供文档的索引。可以避免达到集群资源限制。示例,您可以在单个索引中包含 tenant_id 和其他共享或租户特定的字段。

  • 简化维护操作

    由于只有一个集合存储所有数据,因此您不必维护多个集合或跨多个数据库扩展资源。您还可以简化备份、分片和复制操作,因为您只需针对单个数据库中的单个集合。

  • 高效处理查询

    您可以使用tenant_id $search.compound.filter子句中的 等于运算操作符在查询中提供 字段作为过滤。

    注意

    查询结果将仅包含来自匹配租户的文档,从而防止数据跨租户泄漏。

如果您托管的租户股票相似的访问权限模式和资源大小,则此策略还可以使Lucene索引字段数保持较低水平。

重要

当每个租户都有较高的写入负载时,将所有租户并置到单个集合中可能会导致写入争用。在这种情况下,可以考虑将写入次数最多的租户拆分到单独的集合中,以便将写入负载分布到更多的根本的资源。

如果您的大型租户具有独特的资源或索引需求,请使用视图:

  1. 隔离租户。使用带有 操作的 $match$expr创建视图,以仅过滤租户的文档。

  2. 单独索引。在视图上创建MongoDB Search索引。

    这样,您就可以为大型租户自定义索引定义,而不会影响其他租户使用的共享索引。所有其他租户都可以使用单个索引。

    我们建议每个集群不要超过 2500 个索引,因为这会在基础集群上产生高负载,并有扰乱数据库工作负载的风险。

如果您当前应用每个租户一个集合策略,我们建议扩展基础层级,以防止由于大量索引的资源争用而导致复制延迟 OOM 错误增加。我们还建议迁移到所有租户的同一个集合策略。

如果特定租户有大量写入负载,则可能会导致共享集合发生争用。我们建议您仅将流量最大的租户移动到单独的集合中,以分配 I/O 负载。

如果某个租户需要唯一索引或明显大于其他租户,请使用MongoDB视图:

  • 创建视图,使用

  • $match 仅过滤该租户的文档。

  • 在该视图上创建MongoDB Search索引。这样就可以对异常租户进行定制,而不会中断大多数租户使用的共享索引。

在每租户数据库设置中,每个租户都包含自己的数据库。此设置会隔离租户数据,但也会成倍增加集群中的索引数量。当每个租户有许多索引字段时,集群可能会达到 2500-索引上限。

警告

大量索引会在基础集群上产生大量负载,并可能扰乱您的工作负载。为保持集群稳定,请仔细监控索引数量,避免索引总数超过 2500 个。

每个租户的集合策略将每个租户映射到共享数据库中自己的集合。维护每个集合的索引的开销可能会导致:

  • 复制延迟增加

  • 由于资源争用而导致的 OOM 错误

  • 基础层级不稳定

我们不建议对MongoDB Search 使用这种策略,除非租户具有非常可预测的轻量级工作负载。如果您当前使用此策略,迁移到所有租户的一个集合策略。

请考虑以下建议来管理索引字段:

后退

查看部署选项

在此页面上