【发布时间】:2017-06-30 00:09:38
【问题描述】:
在浏览 mongodb 分片教程时,我遇到了以下断言:
“如果你在查询中使用分片键,它会命中少量分片,通常只有一个”
另一方面,根据我早期的一些分片基础知识,我的印象是,如果在 Shard Key 上触发查询,mongos 路由服务可以唯一地指出目标分片。我的问题是 - 在什么情况下,基于分片键的查询有可能命中多个分片?
【问题讨论】:
在浏览 mongodb 分片教程时,我遇到了以下断言:
“如果你在查询中使用分片键,它会命中少量分片,通常只有一个”
另一方面,根据我早期的一些分片基础知识,我的印象是,如果在 Shard Key 上触发查询,mongos 路由服务可以唯一地指出目标分片。我的问题是 - 在什么情况下,基于分片键的查询有可能命中多个分片?
【问题讨论】:
使用分片键的查询将针对分片子集来检索查询数据,但根据查询和数据分布,这可能少至一个或多于所有分片。
从shard keys 上的 MongoDB 文档中借用一张有用的图片:
MongoDB 使用 shard key 将数据自动划分为称为 chunks 的 shard key 值的逻辑范围。默认情况下,每个块代表大约 64MB 的数据,并与当前拥有该范围的分片键值的单个分片相关联。块数为balanced across available shards,并且不期望相邻块在同一个分片上。
如果您查询属于单个块的分片键值(或值范围),mongos 绝对可以针对单个分片。
假设块范围如上图所示:
// Targeted query to the shard with Chunk 3
db.collection.find( { x: 50 } )
// Targeted query to the shard with Chunk 4
db.collection.find( {x: { $gte: 200} } )
如果您的查询跨越多个块范围,mongos 可以针对包含相关文档的分片子集:
// Targeted query to the shard(s) with Chunks 3 and 4
db.collection.find( {x: { $gte: 50} } )
此示例中的两个块将位于同一个分片或两个不同的分片上。您可以查看explain results 进行查询,以了解有关访问了哪些分片的更多信息。
也可以构造一个需要来自所有分片的数据的查询(例如,基于大范围的分片键值):
// Query includes data from all chunk ranges
db.collection.find( {x: { $gte: -100} } )
注意:以上信息描述了基于范围的分片。 MongoDB 还支持基于散列的分片键,它将(有意)在散列后将相邻的分片键值分配到不同的块范围。对散列分片键的范围查询预计将包括多个分片。见:Hashed vs Ranged Sharding。
【讨论】: