基于碎片键命中多个碎片的查询

Query based on shard key hitting multiple shards

在浏览 mongodb 分片教程时,我遇到了以下断言:

"If you use shard key in the query, its going to hit a small number of shards, often only ONE"

另一方面,根据我早期对分片的一些基础知识,我的印象是,如果在 Shard Key 上触发查询,mongos 路由服务可以唯一地指出目标分片。我的问题是 - 在什么情况下,基于分片键的查询有可能命中多个分片?

使用分片键的查询将以分片子集为目标来为您的查询检索数据,但根据查询和数据分布,这可能少至一个分片,也可能与所有分片一样多。

shard keys 上的 MongoDB 文档中借用一张有用的图片:

MongoDB 使用分片键自动将数据划分为分片键值的逻辑范围,称为 chunks。默认情况下,每个块代表大约 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} } )

注意:以上信息描述了range-based分片。 MongoDB 还支持 hash-based 分片键,它将(有意地)在散列后将相邻的分片键值分布到不同的块范围。散列分片键的范围查询预计包括多个分片。参见:Hashed vs Ranged Sharding.