2017-02-11 71 views
1

虽然我碰到下面的断言来浏览MongoDB的分片教程:查询基于片键击中多个碎片

“如果你在查询中使用片键,它会打少数碎片,经常只有一个“

另一方面,从我之前关于分片的一些基本知识来看,如果查询是在Shard Key上触发的,mongos路由服务可以唯一地指出目标分片。我的问题是 - 在什么情况下,基于分片键的查询有可能触及多个分片?

回答

1

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

借用上shard keys从MongoDB的文档一个有用的图像: Shard key example from MongoDB documentation

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