在集群中, mongos 负责将查询与写入分发到 分片 中.使用 mongos,应用有了访问集群的统一入口,而不须要直接访问集群的每一个分片.html
经过缓存 配置服务器 中集群的元信息, mongos 能够得知数据所位于的分片. mongos 使用这些元信息将应用的读写请求分发到不一样的分片, mongos 不存储集群 持续 的状态(意思是, mongos 能够随时被重启或者添加,而不会形成集群的数据丢失,也不会形成集群的异常.),而且占有较少的系统资源.数据库
最多见的作法是将 mongos 运行在应用所在的系统上,不过在分片上或者其余专用的机器上运行也是能够的.缓存
"mongos" 如何决定哪一个分片应该接收到请求服务器
在 cluster <sharded cluster>`中, :program:`mongos 使用如下步骤分发请求:数据结构
肯定必须接收请求的 分片 列表.app
在全部目标分片上创建游标 在某些状况下,当查询条件包含 shard key 或者 shard key 的前缀时,:program:mongos 能够将请求分发到部分分片上,不然, mongos 会将请求分发到 全部 存储这个集合的分片上. ``mongos``如何处理查询修饰符 若是查询结果没有排序, mongos 会打开一个结果游标,对全部分片的游标依次轮询取得数据.若是查询经过 sort() 指明要排序, mongos 会将 $orderby 选项发送给全部分片,当 mongos 接收到结果以后,会先进行 合并排序 再返回给应用程序.若是查询经过 limit() 限制了返回文档的数量, mongos 会将这个限制发送到全部分片,而且在返回给应用程序以前再次使用这个限制对结果进行过滤.若是查询经过 skip() 指定了要 跳过 的文档数目, mongos 不能 将跳过的数目发送到分片,而必须先从分片接收到全部未经跳过的数据,再使用跳过的数量对结果进行检索,不过,在联合使用 limit() 与 skip() 进行查询时,为了更高效一些, mongos 会将 限制 与 *跳过*一块儿发送给分片. 检测链接的是否为 mongos 为了检测应用链接的是否是 mongos,可使用 isMaster 命令.若是应用链接的是一个 mongos , isMaster 返回一个包含 isdbgrid 字符串的 msg ,好比:
若是应用链接的是 mongod ,返回的文档中不包含 isdbgrid 字符串.less
通常来讲,集群中的操做分为以下两种: 向存储集合的全部分片中广播发送的操做. 基于片键,向集群中单个或部分分片发送的操做. 为了得到更好的性能,最好在任何可能的时候都使用具备特定目标的操做.虽然有些操做不得不使用广播发送的形式,你也应该尽量在进行操做时带有片键来尽量使用具备特定目标的操做.性能
mongos instances broadcast queries to all shards for the collection unless the mongos can determine which shard or subset of shards stores this data.ui
多文档更新操做老是会被分发到全部分片.this
除非操做指定了完整的片键,不然 remove() 将老是广播式操做.
全部的 insert() 都会分发到某一个分片上.
全部的单个 update() (包括 upsert 操做) 与 remove() 操做都会被发往一个分片.
包含片键或部分片键的查询, mongos 能够将查询分发到特定的一个分片或几个分片上.
分片行为是以集合为基本单位的,你能够在一个数据库中对多个集合开启分片,也能够拥有多个打开分片的数据库. [2] 不过,在生产环境中,会存在一些数据库和集合开启了分片,另外一些数据库和集合没有开启分片的状况.
无论 sharded cluster 中数据结构如何,应该一直使用 mongos 访问集群数据,即便对于未分片的数据也应当如此.
[2] | 在你配置分片的时候,应该使用 enableSharding 对数据库开启分片,才能在以后使用 shardCollection 为某个集合开启分片. |