mongos
MongoDB mongos
实例将查询和写入操作路由到分片集群中的分片。从应用程序的角度来看,mongos
提供了通向分片集群的唯一接口。应用程序永远不会与分片直接连接或通信。
mongos
通过缓存来自配置服务器的元数据来跟踪哪个分片上有哪些数据。mongos
使用该元数据将操作从应用程序和客户端路由到 mongod
实例。mongos
没有持久状态,且会使用最少的系统资源。
最常见的做法是在与应用程序服务器相同的系统上运行 mongos
实例,但是您也可以在分片或其他专用资源上维护 mongos
实例。另请参阅 mongos
的数量和分布。
路由和结果进程
确定必须接收查询的分片的列表。
在所有目标分片上建立游标。
然后,mongos
会合并来自每个目标分片的数据,并返回结果文档。在 mongos
检索结果之前,会对每个分片执行某些查询修饰符,例如 排序。
如果结果不需要在数据库的主分片上运行,则在多个分片上运行的聚合操作可能会将结果路由回mongos
以合并结果。
在两种情况下,管道没有资格在 mongos
上运行。
当分割管道的合并部分包含必须在主分片上运行的阶段时,会出现第一种情况。例如,如果 $lookup
需访问与运行该聚合的分片集合位于同一数据库中的未分片集合,则必须在主分片上运行合并操作。
当分割管道的合并部分包含可能将临时数据写入磁盘的阶段(例如$group
)并且客户端指定了allowDiskUse:true
时,会发生第二种情况。在这种情况下,假设合并管道中没有其他阶段需要主分片,则合并在聚合目标分片集中随机选择的分片上运行。
有关如何在分片集群查询的各组件之间分割聚合的更多信息,请将 explain:true
用作 aggregate()
调用的参数。返回的内容包含三个 json 对象。mergeType
会显示合并阶段发生的位置(“primaryShard”、“anyShard”或“mongos”)。splitPipeline
则显示管道中的哪些操作已在各分片上运行。shards
会显示每个分片已完成的工作。
在某些情况下,当分片键或分片键的前缀是查询的一部分时,mongos
会执行定向操作,将查询路由到集群中的分片子集。
mongos
对不包含分片键的查询执行广播操作,将查询路由到集群中的所有分片。某些包含分片键的查询仍可能导致广播操作,具体取决于集群中数据的分布和查询的选择性。
有关定向操作和广播操作的更多信息,请参阅定向操作与广播操作。
mongos
如何处理查询修饰符
排序
如果查询结果未进行排序,mongos
实例则会将打开一个结果游标,而该游标由分片上的所有游标“循环”生成。
限制
如果查询使用 limit()
游标方法限制结果集的大小,则 mongos
实例会将该限制传递给分片,然后在将结果返回给客户端之前将限制重新应用于结果。
跳过
如果查询使用 skip()
游标方法指定要跳过的记录数量,则 mongos
无法将此跳过传递给分片,而是从分片中检索未跳过的结果,并在汇编完整结果时跳过相应数量的文档。
读取偏好和分片
对于分片集群,mongos
在从分片读取数据时会应用读取偏好。所选成员同时受读取偏好和 replication.localPingThresholdMs
设置的控制,并且会针对每项操作得到重新评估。
有关读取偏好和分片集群的详细信息,请参阅读取偏好和分片。
对冲读 (Hedged Reads)
mongos
实例可以对冲使用非 primary
读取偏好的读取。通过对冲读,mongos
实例将读取操作路由到每个查询分片的两个副本集成员,并从每个分片的第一个响应者返回结果。为对冲读取操作而发送的其他读取使用 maxTimeMSForHedgedReads
的 maxTimeMS
值。
以下操作支持对冲读:
对冲读和读取偏好
作为读取偏好的一部分,为每个操作都指定了对冲读。非 primary
读取偏好支持对冲读。请参阅对冲读取偏好选项。
要为非
primary
读取偏好指定对冲读,请参阅驱动程序读取偏好 API 文档。读取偏好
nearest
默认启用对冲读选项。
有关读取偏好和分片集群以及成员选择的详细信息,请参阅读取偏好和分片。
启用/禁用对冲读支持
默认情况下,mongos
实例支持使用对冲读。要关闭 mongos
实例对对冲读的支持,请参阅 readHedgingMode
参数。如果对冲读支持为 off
,则无论为读取偏好指定的 hedge
选项为何,mongos
均不会使用对冲读。
对冲读诊断
serverStatus
命令及其对应的 mongosh
方法 db.serverStatus()
会返回 hedgingMetrics
。
确认连接到mongos
实例
要检测客户端连接的 MongoDB 实例是否为mongos
,请使用hello
命令。当客户端连接到mongos
时,hello
会返回一个包含字符串isdbgrid
的msg
字段的文档。例如:
{ "isWritablePrimary" : true, "msg" : "isdbgrid", "maxBsonObjectSize" : 16777216, "ok" : 1, ... }
如果应用程序连接到 mongod
,则返回的文档不包含 isdbgrid
字符串。
定向操作与广播操作
通常,分片环境中最快的查询是那些 mongos
使用分片键和来自配置服务器的集群元数据路由到单个分片的查询。这些有针对性的操作使用分片键值来定位满足查询文档的分片或分片子集。
对于不包含分片键的查询,mongos
必须查询所有分片,等待其响应,然后将结果返回给应用程序。这些“分散/聚集”查询可能会长时间运行。
广播操作
mongos
实例会向集合的所有分片广播查询,除非 mongos
可以确定哪个分片或分片子集存储此数据。
在mongos
收到所有分片的响应后,它会合并数据并返回结果文档。广播操作性能取决于集群的整体负载,以及网络延迟、单个分片负载和每个分片返回的文档数量等变量。尽可能选择引起针对性操作而非广播操作的操作。
多更新操作始终是广播操作。
updateMany()
和 deleteMany()
方法为广播操作,除非查询文档完整指定了分片键。
定向操作
mongos
可以将包含分片键或复合分片键前缀的查询路由到特定分片或分片集。mongos
使用分片键值来定位范围包含分片键值的数据段,并将查询指向包含该数据段的分片。
例如,如果分片键是:
{ a: 1, b: 1, c: 1 }
mongos
程序可以可以将包含完整分片键或以下任一分片键前缀的查询路由到特定的分片或分片集:
{ a: 1 } { a: 1, b: 1 }
所有 insertOne()
操作都以一个分片为目标。insertMany()
数组中的每个文档都以单个分片为目标,但不能保证数组中的所有文档都插入到单个分片中。
所有 updateOne()
、replaceOne()
和 deleteOne()
操作都必须在查询文档中包含分片键或 _id
。 如果在没有分片键或_id
的情况下使用这些方法,MongoDB 将返回错误。
索引使用
分片收到查询时,会使用最高效的可用索引来完成该查询。使用的索引可能是分片键索引,也可能是分片上存在的另一个合格索引。
分片集群的安全性
使用自管理的内部/节点身份验证来执行集群内部安全,防止未经授权的集群组件访问集群。您必须使用适当的安全设置启动集群中的每个 mongod
或 mongos
,才能实施内部身份验证。
从 MongoDB 5.3 开始,SCRAM-SHA-1不能用于集群内身份验证。仅支持 SCRAM-SHA-256。
在先前的 MongoDB 版本中,SCRAM-SHA-1 和 SCRAM-SHA-256 均可用于集群内身份验证,即使未显式启用 SCRAM。
有关部署安全分片集群的教程,请参阅使用密钥文件身份验证部署自管理分片集群。
集群用户
分片集群支持自管理部署中基于角色的访问控制 (RBAC),以限制对集群数据和操作进行未经授权的访问。要执行 RBAC,必须使用 --auth
选项来启动集群中的每个 mongod
,包括配置服务器。或者,为集群间安全执行自管理内部/成员身份验证还可以通过 RBAC 实现用户访问控制。
强制执行 RBAC 后,客户端在连接到 mongos
时必须指定 --username
、--password
和 --authenticationDatabase
才能访问集群资源。
每个集群都有自己的集群用户。这些用户不能用于访问单个分片。
有关向已启用 RBAC 的 MongoDB 部署中添加用户的教程,请参阅在自管理部署中启用访问控制。
元数据操作
对于影响分片集群元数据的以下操作,mongos
使用 "majority"
写关注:
更多信息
fCV 兼容性
mongos
二进制文件无法连接到特征兼容性版本 (fCV) 高于 mongos
的 mongod
实例。例如,您无法将 MongoDB 4.0 版本 mongos
连接到 fCV 设置为 4.2 的 4.2 分片集群。但是,您可以将 MongoDB 4.0 版本 mongos
连接到 fCV 设置为 4.0 的 4.2 分片集群。
全时诊断数据捕获要求
mongod
包括全时诊断数据捕获机制,以协助 MongoDB 工程师对部署进行故障排除。如果该线程失败,它将终止原始进程。为了避免出现最常见的故障,请确认运行该进程的用户有权创建 FTDC diagnostic.data
目录。对于 mongod
,该目录位于 storage.dbPath
内。对于 mongos
,该目录与 systemLog.path
并行。
连接池
从 MongoDB 4.2 开始,MongoDB 添加了 ShardingTaskExecutorPoolReplicaSetMatching
参数。该参数确定 mongod
/mongos
实例到每个分片集群节点的连接池的最小大小。该值可能会在运行时发生变化。
mongod
和 mongos
为分片集群的每个副本集维护连接到每个辅助副本集的连接池。默认情况下,这些连接池的连接数至少等于主节点的连接数。
要进行修改,请参阅 ShardingTaskExecutorPoolReplicaSetMatching
。
使用带集群的聚合管道
有关分片如何与聚合配合使用的更多信息,请阅读实用 MongoDB 聚合电子书中的“分片”章节。