当排序字段不是分片键的一部分时,mongos 会将查询发送到所有 mongod 实例。在所有 mongod 实例返回数据后,mongos 会将它们合并。
此合并操作是否包括排序?
我们知道 sort 字段不是 shard key 的一部分,所以返回的数据应该是无序的,mongos 必须进行排序。如果是这样,当返回的数据非常大时,mongos会占用大量内存。
我的理解正确吗?
这不是分片键中需要的排序字段,而是您用来选择数据的标准。也就是说,如果 mongos 无法从您用作查询的一部分的字段中确定数据的具体位置,那么它将发送到所有分片。这与任何其他非排序查询相同。对非 shardkey 字段进行排序不会影响 mongos 正确路由查询的能力。
此处的文档中提到了这一点:
https://docs.mongodb.org/v2.4/core/sharded-cluster-query-router/#how-mongos-handles-query-modifiers
分片将接收来自 mongos 的查询,它们将对结果子集进行排序,并将它们发送回 mongos。然后,mongos 必须在返回结果之前对返回的结果进行合并排序。这不像完整排序那样密集,因为结果最初是按分片排序的,但仍然需要资源。消耗的内存量将与各个分片返回的结果集的大小有关。
编辑(2016 年 5 月):上述内容在 2012 年最初回答时是正确的,但是(如下面的评论中指出的)行为在 2014 年随着版本 2.6 发生了变化。结果现在被发送到主分片,以便分片数据库成为在返回给 mongos(然后返回给用户)之前进行合并排序。这很有意义,因为mongos
实例不太可能拥有执行大型排序的资源,但这确实意味着您应该密切注意将频繁排序的任何数据库的主要位置,因为它会看到更高的负载因此。
在 3.2 版本中,如果在 fetch 中没有使用主 shard(换句话说,主 shard 不包含 find 命令中的任何文档),则可以使用辅助 shard 代替。