mongos

在本页面

MongoDB mongos实例将查询路由并向分 Cluster 群集中的shards写入操作。从应用程序的角度来看,mongos提供了分片群集的唯一接口。应用程序永远不会与分片直接连接或通信。

mongos通过缓存config servers的元数据来跟踪哪个分片上的数据。 mongos使用元数据将操作从应用程序和 Client 端路由到mongod实例。 mongos没有* persistent *状态,并且消耗最少的系统资源。

最常见的做法是在与应用程序服务器相同的系统上运行mongos实例,但是您可以在分片或其他专用资源上维护mongos实例。

路由和结果流程

mongos实例通过以下方式将查询路由到cluster

  • 确定必须接收查询的shards列表。

  • 在所有目标分片上构建光标。

mongos然后合并来自每个目标分片的数据并返回结果文档。在mongos检索结果之前,会对每个分片执行某些查询修饰符,例如sorting

在版本 3.6 中进行了更改:对于在多个分片上运行的aggregation operations,如果这些操作不需要在数据库的primary shard上运行,则这些操作可能会将结果路由回mongos,然后合并结果。

在两种情况下,管道不适合在mongos上运行。

第一种情况发生在拆分管道的合并部分包含必须在主碎片上运行的阶段时。例如,如果$lookup要求访问与运行聚合的分片集合在同一数据库中的未分片集合,则合并必须在主分片上运行。

第二种情况是,当拆分管道的合并部分包含一个阶段,该阶段可以将临时数据写入磁盘,例如$group,并且 Client 端指定了allowDiskUse:true。在这种情况下,假设合并管道中没有其他需要主分片的阶段,则合并将在聚集目标的分片集中随机选择的分片上运行。

有关聚合工作如何在分片群集查询的各个组件之间分配的更多信息,请使用explain:true作为aggregation()调用的参数。返回将包括三个 json 对象。 mergeType显示合并阶段发生的位置(“ primaryShard”,“ anyShard”或“ mongos”)。 splitPipeline显示管道中的哪些操作在单个分片上运行。 shards显示每个分片已完成的工作。

在某些情况下,当shard key或分片键的前缀是查询的一部分时,mongos执行targeted operation,将查询路由到群集中的分片的子集。

mongos对不包含shard key的查询执行broadcast operation,将查询路由到集群中的所有*碎片。确实包含分片键的某些查询可能仍会导致 Broadcast 操作,具体取决于群集中数据的分布和查询的选择性。

有关定向和 Broadcast 操作的更多信息,请参见目标运营与 Broadcast 运营

mongos 如何处理查询修饰符

Sorting

如果查询的结果未排序,则mongos实例将打开一个结果游标,该游标将对分片上的所有游标进行“轮循”。

Limits

如果查询使用limit()游标方法限制了结果集的大小,则mongos实例将该限制传递给分片,然后将该限制重新应用于结果,然后再将结果返回给 Client 端。

Skips

如果查询使用skip()游标方法指定要跳过的记录数量,则mongos无法将跳过传递给分片,而是从分片中检索未跳过的结果,并在组装完整结果时跳过适当数量的文档。

limit()结合使用时,mongos会将* limit *加上skip()的值传递给分片,以提高这些操作的效率。

确认与 mongos 实例的连接

要检测您的 Client 端连接到的 MongoDB 实例是否为mongos,请使用isMaster命令。当 Client 端连接到mongos时,isMaster返回带有msg字段的文档,该字段包含字符串isdbgrid。例如:

{
   "ismaster" : true,
   "msg" : "isdbgrid",
   "maxBsonObjectSize" : 16777216,
   "ok" : 1,
   ...
}

如果应用程序改为连接到mongod,则返回的文档不包含isdbgrid字符串。

目标操作与 Broadcast 操作

通常,分片环境中最快的查询是使用_和来自config server的集群元数据mongos路由到单个分片的查询。这些targeted operations使用分片键值来定位满足查询文档的分片或分片子集。

对于不包含分片键的查询,mongos必须查询所有分片,await 它们的响应,然后将结果返回给应用程序。这些“分散/聚集”查询可能是长时间运行的操作。

Broadcast Operations

mongos实例向集合的所有分片 Broadcast 查询,除非mongos可以确定哪个分片或分片子集存储此数据。

将操作读取到分片群集。查询条件不包含分片键。查询 Routermongos 必须将查询 Broadcast 到所有分片以进行收集。

mongos收到所有分片的响应后,它将合并数据并返回结果文档。Broadcast 操作的性能取决于群集的总体负载,以及诸如网络延迟,单个分片负载以及每个分片返回的文档数之类的变量。只要有可能,请优先选择导致targeted operation的操作,而不是导致 Broadcast 操作的操作。

多次更新操作始终是 Broadcast 操作。

updateMany()deleteMany()方法是 Broadcast 操作,除非查询文档完整指定了分片键。

Targeted Operations

mongos可以路由包含分片密钥或compound分片密钥的前缀,特定分片或一组分片的查询。 mongos使用分片键值来定位其范围包括分片键值的chunk并将查询定向到包含该块的shard

将操作读取到分片群集。查询条件包括分片键。查询 Routermongos 可以将查询定位到适当的一个或多个分片。

例如,如果分片键为:

{ a: 1, b: 1, c: 1 }

mongos程序可以路由查询,这些查询包括特定分片或一组分片的完整分片键或以下分片键前缀之一:

{ a: 1 }
{ a: 1, b: 1 }

所有insertOne()个操作都针对一个分片。 insertMany()数组中的每个文档都指向一个分片,但是不能保证数组中的所有文档都插入到一个分片中。

所有updateOne()replaceOne()deleteOne()操作必须在查询文档中包含shard key_id。如果使用的这些方法没有分片键或_id,则 MongoDB 将返回错误。

取决于群集中数据的分布和查询的选择性,mongos仍可以执行broadcast operation来满足这些查询。

Index Use

如果查询不包括shard key,则mongos必须将查询作为“散布/聚集”操作发送给所有分片。每个分片将依次使用分片键索引或另一个更有效的索引来满足查询。

如果查询包括多个子表达式,这些子表达式引用由分片键辅助索引索引的字段,则mongos可以将查询路由到特定分片,并且分片将使用使它最有效地执行的索引。

分片群集安全性

使用Internal Authentication来增强群集内部的安全性,并防止未经授权的群集组件访问群集。您必须使用适当的安全设置启动群集中的每个mongodmongos,以强制执行内部身份验证。

有关部署安全分片群集的教程,请参见使用密钥文件访问控制部署分片群集

Cluster Users

分片群集支持基于角色的访问控制 (RBAC),用于限制对群集数据和操作的未授权访问。您必须使用--auth选项启动集群中的每个mongod,包括config servers,以实施 RBAC。另外,对集群间安全性实施Internal Authentication也可以通过 RBAC 启用用户访问控制。

在强制执行 RBAC 的情况下,Client 端必须在连接到mongos时指定--username--password--authenticationDatabase才能访问群集资源。

每个集群都有自己的集群用户。这些用户不能用来访问各个分片。

有关启用用户添加到启用 RBAC 的 MongoDB 部署的教程,请参阅Enable Auth