mongos
MongoDBmongos
实例将查询和写操作路由到分片集群中的分片。 mongos
为应用程序提供了访问分片集群的唯一接口。应用程序从不直接连接或与分片通信。
mongos
通过缓存来自配置服务器的元数据来跟踪每个分片上的数据。 mongos
使用元数据将应用程序和客户端的操作路由到mongod
实例。 mongos
没有持久状态,消耗的系统资源最少。
最常见的做法是在与应用程序服务器相同的系统上运行mongos
实例,但您可以在分片或其他专用资源上维护mongos
实例。另请参阅mongos
数量和分布。
路由和结果处理过程
mongos
实例通过以下方式将查询路由到集群:
确定必须接收查询的
分片
列表。在所有目标分片上建立游标。
mongos
然后合并来自每个目标分片的数据,并返回结果文档。某些查询修饰符,如排序,在mongos
检索结果之前在每个分片上执行。
聚合操作在多个分片上运行时,如果不需要在数据库的主分片上运行,可能会将结果路由回mongos
以合并结果。
有几种情况会导致管道无法在mongos
上运行。
第一种情况发生在拆分管道的合并部分包含一个必须在特定分片上运行的阶段。例如,如果$lookup
需要访问与正在运行的聚合相同的数据库中的非分片集合,合并将在托管非分片集合的分片上运行。
第二种情况发生在拆分管道的合并部分包含一个可能将临时数据写入磁盘的阶段,例如$group
,并且客户端指定了allowDiskUse:true
。在这种情况下,假设合并管道中没有其他阶段需要主分片,合并将在聚合目标集中的随机选择分片上运行。
有关聚合工作如何在分片集群查询的组件之间分割的更多信息,请在aggregate()
调用中将explain:true
作为参数。返回结果包括三个JSON对象
mergeType
显示合并阶段发生在何处("primaryShard","anyShard","specificShard"或"mongos")。当mergeType
是specificShard
时,聚合输出包括一个mergeShard
属性,其中包含合并分片的分片ID。splitPipeline
显示您的管道中哪些操作在单个分片上运行。shards
显示每个分片完成的工作。
在某些情况下,当分片键或分片键的前缀是查询的一部分时,mongos
执行定向操作,将查询路由到集群中分片的一个子集。
mongos
执行广播操作,针对不包含分片键的查询,将查询路由到集群中的所有分片。一些包含分片键的查询可能仍然会导致广播操作,具体取决于集群中数据的分布和查询的选择性。
有关定向操作和广播操作的更多信息,请参阅定向操作与广播操作。
如何处理查询修饰符 mongos
排序
如果查询结果未排序,mongos
实例将打开一个结果游标,该游标“轮询”来自所有分片游标的结果。
限制
如果查询使用 limit()
游标方法限制结果集大小,则 mongos
实例将此限制传递到分片,然后在返回结果给客户端之前重新应用该限制。
跳过
如果查询指定使用skip()
游标方法跳过记录数,则mongos
无法将跳过的值传递给分片,而是从分片检索未跳过的结果,并在组装完整结果时跳过适当的文档数。
读取偏好和分片
对于分片集群,当从分片读取时,mongos
应用读取偏好
。所选成员由读取偏好
和replication.localPingThresholdMs
设置控制,并且对每个操作都会重新评估。
有关读取偏好和分片集群的详细信息,请参阅读取偏好和分片。
保险阅读
重要
从MongoDB 8.0开始,权衡读取已弃用。指定读取优先级 nearest
的查询默认不再使用权衡读取。如果您明确指定了权衡读取,MongoDB将执行权衡读取并记录警告。
mongos
实例可以对使用非 primary
读取优先级 的读取进行权衡。在权衡读取中,mongos
实例将读取操作路由到每个查询分片的两个副本集成员,并从每个分片的第一响应者返回结果。用于权衡读取操作的多余读取使用 maxTimeMSForHedgedReads
的 maxTimeMS
值。
权衡读取支持以下操作
权衡读取和读取优先级
权衡读取作为读取优先级的一部分指定,每个操作都支持权衡读取。非 primary
读取优先级支持权衡读取。请参阅权衡读取优先级选项。
要为非
primary
读取优先级指定权衡读取,请参考驱动程序 读取优先级API文档。读取优先级
nearest
默认启用权衡读取选项。
有关读取优先级、分片集群以及成员选择的详细信息,请参阅读取优先级和分片。
启用/禁用对对冲读取的支持
默认情况下,mongos
实例支持使用对冲读取。要关闭 mongos
实例对对冲读取的支持,请查看 readHedgingMode
参数。如果对冲读取支持关闭(off
),则 mongos
不使用对冲读取,无论指定了哪种读取偏好选项。
对冲读取诊断
命令 serverStatus
及其对应的 mongosh
方法 db.serverStatus()
返回 hedgingMetrics
。
确认连接到 mongos
实例
为了检测客户端连接到的 MongoDB 实例是否为 mongos
,请使用 hello
命令。当客户端连接到 mongos
时,hello
返回一个包含 msg
字段的文档,其中包含字符串 isdbgrid
。例如
{ "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 会返回错误。
根据集群中数据的分布和查询的选择性,mongos
可能仍然会执行广播操作以满足这些查询。
索引使用
当分片接收到一个查询时,它会使用最有效的索引来满足该查询。所使用的索引可以是 分片键索引 或分片上存在的其他符合条件的索引。
分片集群安全性
使用 自管理内部/成员身份验证 来强制执行集群内部安全性并防止未经授权的集群组件访问集群。您必须以适当的设置启动集群中的每个 mongod
或 mongos
,以强制执行内部身份验证。
从MongoDB 5.3版本开始,SCRAM-SHA-1不能再用于集群内部认证。仅支持SCRAM-SHA-256。
在MongoDB的早期版本中,即使SCRAM没有被显式启用,SCRAM-SHA-1和SCRAM-SHA-256都可以用于集群内部认证。
有关部署安全分片集群的教程,请参阅使用密钥文件认证部署自管理分片集群。
集群用户
分片集群支持自管理部署中的基于角色的访问控制(RBAC),以限制对集群数据和操作的未授权访问。您必须使用--auth
选项在每个集群中启动每个mongod
,包括配置服务器,以实施RBAC。或者,通过实施集群安全性的自管理内部/成员认证,也可以通过RBAC启用用户访问控制。
实施RBAC后,客户端在连接到mongos
以访问集群资源时,必须指定一个--username
、--password
和--authenticationDatabase
。
每个集群都有自己的集群用户。这些用户不能用于访问单个分片。
有关如何向RBAC启用的MongoDB部署添加用户的教程,请参阅在自管理部署上启用访问控制。
元数据操作
mongos
在以下影响分片集群元数据的操作中使用 "majority"
写关注度:
附加信息
功能兼容性版本兼容性
二进制程序 mongos
无法连接到其 mongod
实例的功能兼容性版本(fCV)高于 mongos
的实例。例如,您不能将 MongoDB4.0版本 mongos
连接到具有4.2功能兼容性版本(fCV)设置为4.2的4.0版本 mongos
连接到具有4.2功能兼容性版本(fCV)设置为4.0.
全职诊断数据捕获要求
mongod
包含一个 全职诊断数据捕获 机制,以协助 MongoDB 工程师进行部署故障排除。如果此线程失败,则终止原始进程。为了避免最常见的故障,请确认运行进程的用户具有创建 FTDC diagnostic.data
目录的权限。对于 mongod
,该目录位于 storage.dbPath
内。对于 mongos
,它与 systemLog.path
平行。
连接池
从 MongoDB 4.2 版本开始,MongoDB 添加了参数 ShardingTaskExecutorPoolReplicaSetMatching
。此参数确定 mongod
/ mongos
实例的连接池到分片集群的每个成员的最小大小。此值可以在运行时变化。
mongod
和 mongos
为分片集群中的每个分片集的每个副本集维护连接池。默认情况下,这些池中的连接数至少与主机的连接数相同。
使用集群中的聚合管道
有关分片如何与聚合一起工作的更多信息,请阅读《Practical MongoDB Aggregations》中关于分片的章节:Practical MongoDB Aggregations 电子书。