为多租户mongodb应用生成分片键字段

时间:2014-10-18 22:59:55

标签: mongodb mongoose sharding

我正在研究在mongodb上运行的多租户应用程序。每个租户都可以创建多个应用程序。大多数集合的模式通过ObjectID引用其他集合。我正在考虑以下列格式手动创建每个记录插入的分片键:

(记录的ObjectId的v3 murmurhash)+(app_id.toHexString())

这是否足以确保任何特定应用程序的记录可能最终都在同一个分片上?

此外,如果特定应用程序与分片上的所有其他应用程序相比变得超大,会发生什么?

1 个答案:

答案 0 :(得分:0)

如果你使用基于哈希的分片键,输入不断变化(ObjectID通常可以认为每个记录都是唯一的),那么你根本就不会得到分片上的数据位置(巧合除外) ),虽然它会通过在所有分片中随机分配写入来为您提供出色的写入吞吐量。这基本上是与这种方法的权衡,内置hash based sharding也是如此,这些权衡不会因为它是由两个字段构成的手动哈希而改变。

基本上,因为MongoDB使用基于范围的块来分割给定分片键的数据,在这种情况下,您将使用连续的哈希值作为块。假设您的哈希在某种程度上没有错误,那么单个连续范围内的数据基本上是随机的。因此,即使在单个块中,您也没有数据局部性,更不用说在分片上,它将是完全随机的(按设计)。

如果您希望能够将应用程序组合在一个范围内,因此更有可能位于特定分片上,那么最好先预先安装app_id,使其成为复合分片键中最左侧的字段。对于以下内容进行分片(基于有限的描述)将是一个良好的开端:

{app_id : 1, _id : 1}

虽然ObjectID随着时间的推移会单调增加(对here的更多讨论),但如果有相当数量的应用程序ID,并且您将在ObjectID上进行任何基于范围或目标的查询,那么它可能仍然可以正常工作。您可能还希望根据查询模式包含其他字段。

请记住,无论您最常见的查询模式是什么,您都希望尽可能让分片键(理想情况下)满足它。它必须被编入索引,mongos使用它来决定路由查询(如果没有,那么它是scatter/gather),所以如果你要不断查询{{1} }和app_id然后上面的分片键很有意义。

如果你使用手动哈希键方法,你不仅会有随机分布,而且除非你要查询该哈希值,否则它不会非常有用。