Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs 菜单
Docs 主页
/ /

为MongoDB Vector Search 构建多租户架构

您可以使用MongoDB Vector Search实现多租户,以便应用程序的单个实例为多个租户提供服务。本页介绍专门应用于MongoDB Vector Search 的设计建议。这些建议与我们针对Atlas 的 多租户建议不同。

在为MongoDB Vector Search 设计多租户架构时,请参阅以下建议。

重要

本指导假设您可以在单个 VPC中共置租户。否则,您必须为每个租户维护单独的项目,我们不建议对MongoDB Vector Search 这样做。

我们建议将所有租户数据存储在单个集合以及单个数据库和集群中。您可以通过在每个文档中包含tenant_id 字段来区分租户。此字段可以是租户的任何唯一标识符,例如 UUID 或租户名称。您可以将此字段用作MongoDB Vector Search 索引和查询中的 预筛选器。

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

  • 易于建模和扩展。

  • 简化维护操作。

  • 通过 tenant_id 预过滤以实现高效的查询路由。

    注意

    我们保证不会为不符合此筛选条件的租户提供服务。

由于以下原因,我们建议将每个租户存储在单独的集合或数据库中:

  • 性能影响:此方法可能会导致变更流负载发生变化,具体取决于集合数量,这可能会对性能和监控功能产生负面影响。

  • 无需额外隔离:Atlas中的隔离性ACID 一致性保证应用于数据库级别。在同一数据库中使用单独的集合不会提供额外的数据隔离性优势。使用单独的数据库会带来操作复杂性,对于大多数使用案例来说,没有任何有意义的安全优势。

相反,对所有租户使用一个集合。有关如何从每个租户一个集合模型迁移到单个集合模型的示例,请参阅从每个租户一个集合模型迁移。

请考虑以下策略,使用推荐的方法缓解潜在的性能问题。

如果您有许多租户,每个租户的向量相对较少,或者由于数据分布不均(一些大租户和许多小租户)而遇到性能问题,请考虑以下策略。

如果您有许多租户(最多 1 万),并且每个租户拥有的向量相对较少(每个租户少于 10,000 个向量),请使用 flat索引而不是默认的Hierarchical Navigable Small Worlds索引。要创建平面索引,请在索引定义中将 indexingMethod字段设立为 flat

当每个租户拥有少量向量时,筛选到特定租户的查询已经进行了穷举搜索。在这些情况下,分层可导航小世界 图表没有任何好处,但会增加内存和维护开销。扁平索引消除了这种不必要的开销。

平面索引可为多租户工作负载提供以下优势:

  • 针对选择性过滤器进行了优化:对于每个租户拥有少量向量的高度选择性查询,穷举扫描已经是最快路径。扁平索引直接支持这一点,从而改善延迟和召回。

  • 可预测的性能:无论针对哪个租户,查询延迟都保持在一个狭窄的范围内,从而消除了租户之间的嘈杂邻居影响。

  • 资源效率:扁平索引消除了与构建“分层可导航小世界”图表相关的内存和维护开销。

例子

以下索引定义创建带有 tenant_id过滤器字段的平面索引:

{
"fields": [
{
"type": "vector",
"path": "<fieldToIndex>",
"numDimensions": <numberOfDimensions>,
"similarity": "euclidean | cosine | dotProduct",
"indexingMethod": "flat"
},
{
"type": "filter",
"path": "tenant_id"
}
]
}

注意

平面索引与标量和二进制量化兼容。使用平面索引时,始终将 tenant_id 字段作为 预筛选器 包含在查询中。

对于每个具有超过10 、000 个向量的较大租户,请使用Hierarchical Navigable Small Worlds 索引在MongoDB Views上将大租户与小租户分开:

  • 大型租户(前 1%)

    • 为每个大型租户创建一个视图。

    • 为每个视图创建一个Hierarchical Navigable Small Worlds索引。

    • 维护大型租户的记录,在查询时进行检查,以便相应地路由查询。

  • 小型租户(剩余租户)

    • 为所有小型租户创建单一视图。

    • 为此视图构建单个平面索引

    • 使用 tenant_id 字段作为预过滤器来相应地路由查询。

以下示例演示如何使用 mongosh 为大型和小型租户创建视图:

记录您的大型租户及其相应的 tenant_id 值,然后为每个租户创建一个视图:

db.createView(
"<viewName>",
"<collectionName>",
[
{
"$match": {
"tenant_id": "<largeTenantId>"
}
}
]
)

为小型租户创建视图,过滤掉大型租户:

db.createView(
"<viewName>",
"<collectionName>",
[
{
"$match": {
"tenant_id": {
"$nin": [ "<largeTenantId1>", "<largeTenantId2>", ... ]
}
}
}
]
)

创建视图后,为每个视图创建索引。请验证以下内容:

  • 在为索引指定集合名称时,请使用视图名称而非原始集合名称。

  • 对于大型租户视图,请创建Hierarchical Navigable Small Worlds索引(默认)。

  • 对于小租户视图,使用平面索引方法创建索引,并包含 tenant_id字段作为预筛选器。

有关创建索引的说明,请参阅创建索引页面。

如果您有许多租户,每个租户都有大量向量,请考虑使用基于分区的系统,将数据分发到分片上。

您可以使用 tenant_id 字段作为分片键,根据租户 ID 在特定范围内分发数据。有关更多信息,请参阅范围分片。

要从每个租户一个集合的模型迁移到单个集合的模型,请处理每个租户的集合,并将文档插入到一个新的集合中。

后退

附加建议

在此页面上