MongoDB分片环境下的查询路由

根据2015-01-14官方文档快照翻译(v2.6.7 & v2.8.0-rc4)

翻译 shingo([email protected])


在分片集群环境中,MongoDB通过
mongos实例来路由读写操作。从应用的角度来说,mongos
是访问集群的唯一入口,应用程序不能直接连接集群环境中的分片节点。

通过缓存config节点的元数据信息,
mongos
可以跟踪到数据在哪个分片上。mongos
利用这些元数据信息将应用和客户端的操作路由到具体的mongod
实例。mongos
不提供持久化,并且只消耗很少的系统资源。

最常见的做法是将mongos
实例和应用服务器部署在同一环境下,当然你也可以将mongos
实例和分片节点放在一起,或者用专门的资源来运行它。


注意

2.1版更新。

一些使用aggregate 命令的聚合操作(即db.collection.aggregate())
,会使得mongos 实例较之前的版本需要更多CPU资源。如果你的分片环境中大量使用了aggregation框架,那么你可能要更改部署架构来应对这部分性能上的调整。

路由过程

mongos如何决定由哪些分片来接收一个查询

mongos
路由一个查询到集群中有两步:

  1. 1.  确定接收查询的
    分片
    列表。
  2. 2.  为所有目标分片建立一个游标。

在一些情况下,例如当
shard key
或shard key的某个前辍部分被当做查询条件的一部分时,
mongos
会将查询路由到分片集的某个子集下,其它时候,mongos
将查询引向所有包含目标表数据的分片下。

(译者注:这里所说的shard key的某个前辍部分是指如果是复合key,那么从第一个字段开始按序往后的子集,这个子集对查询时尽可能精确的定位分片有很大帮助,子集越大定位越准。)


示例:

有下面的shard key:

{ zipcode: 1, u_id: 1,
c_date: 1 }

根据集群中具体的chunk分布情况,mongos 可能会将查询路由到一部分分片上,如果查询包括以下字段:

{ zipcode: 1 }

{ zipcode: 1, u_id: 1 }

{ zipcode: 1, u_id: 1,
c_date: 1 }

Mongos如何处理查询修改器

如果查询结果不需要排序,mongos
会开启一个结果游标,从各个目标分片的游标“轮循”结果。

2.0.5版更新:在2.0.5之前的版本中,
mongos
一个接一个将游标从头滑到尾。

(译者注:2.0.5版之前mongos会循环所有目标分片返回的数据集,每一个数据库通过游标从头至尾;从2.0.5开始,mongos开启一个总的游标,每个数据集拿一条数据,循环往复。)

如果查询操作用sort()方法指定了排序规则,
mongos 将$orderby选项传递给各个目标分片。在通过mongos
将结果集返回客户端之前,数据库的主shard会接收所有结果数据,确定后执行合并排序。

如果查询操作用limit()限制结果集的大小,
mongos 将这个限制传递给各个目标分片,在返回客户端之前再将整个结果集缩减到指定大小。

(译者注:如果数据够大,假设有n个目标分片,limit的参数为x,mongodb会至少扫描n*x条数据。
不过在现实的场景中,limit的需求一般为分页,或是专门被指定的一个有限集,这个数在多数情况下不会太大。)

如果查询操作用 skip()方法指定要忽略的结果个数,mongos
不会将这个忽略数传递给目标分片,
而是从各分片检索出符合查询条件的所有结果,在组装最终结果集时再忽略指定数目的数据。但是如果它和limit()方法联合使用,
mongos 将 limit
的值加上skip()
方法的值传递给目标分片,以此来提升这些操作的效率。

(译者注:limit+skip =
每个分片上最终limit值,这也是为了规避查询条件的不同,以及多种因为数据分布引发的结果数据不准确的可能性。
Mongodb的翻页查询随着skip数量的增加性能会越来越差,其实有很多办法可以规避这种查询,比如在主键,或者例用某个字段来精确定位某一页的值范围。)

检测连向mongos的连接

要检测你客户端连接的mongodb实例是否是mongos,可以使用
isMaster 命令。当客户端连上
mongos,isMaster
返回一个带有msg
字段的文档,且字段值为isdbgrid,类似下面这样:


{

"ismaster" : true,

"msg" : "isdbgrid",

"maxBsonObjectSize" : 16777216,

"ok" : 1

}

如果连接的是mongod实例,返回的文档不会包含isdbgrid
字符串。

广播操作和目标操作

一般来说,分片环境里的操作有以下两类:

  • ·       向集群内所有包含某个表数据的分片广播
  • ·       基于shard
    key,有目标的选定某一个分片或某一部分分片

为了获得最佳的性能,尽可能的使用目标操作。而对于一些需要广播到所有分片的操作,如果可以的话在条件里加上shard key让它转变为目标操作。

广播操作

mongos
会将查询广播到所有包含目标表数据的分片上,除非mongos
能搞清楚哪个或哪些分片上存储着目标数据。

批量更新操作属于广播操作。

remove()
操作一般也是广播操作,除非条件中指定了完整的shard key。

目标操作

所有insert()
操作会定位到具体的一个分片。

所有单个 update() (包括upsert
) 和
remove() 也会定位到单独的分片。


重要

指定了justOne
或 multi:false属性的,针对单个分片的update()和 remove() 操作,查询条件中必须包含shard
key或_id字段,否则方法会报错。

对于包含shard key或包含一部分shard key的查询,
mongos
可以定位到具体的某个或多个分片上。这里提到的“一部分shard
key”是指从shard key的第一个字段开始依次往后的前辍部分。举个例子,如果有下面的shard
key:


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

mongos 能够通过查询条件中完整的shard key或者下面两个条件来定位分片:


{ a: 1 }

{ a: 1, b: 1 }

由于数据分布的不同以及查询的多样性,mongos
可能仍然会连接到多个分片
[1]
来完成查询。

[1]如果真的是因为数据分布上的原因,即使查询中包含shard key,mongos
也会将查询路由到所有分片。

分片的和未分片的数据

分片是基于collection级的,你可以在同一个数据库内对多个collection做分片,或者对多个数据库开库分片功能。[2]
但是在生产环境中,一般会有一些数据库和collection使用了分片功能,而其它未开启分片的数据库和collection会存储在单个分片上。

不管你的分片集群环境的数据架构如何,一定要确保所有操作都通过mongos
路由到分片上。即使你的操作针对的是未分片的数据,影响不了分片数据,也要通过mongos
来路由。

[2]
当配置分片功能时,需要使用enableSharding命令为数据库开启分片功能。这个操作也仅仅是为了让该数据库下的collection在分片时能执行shardCollection
命令。

时间: 2024-08-02 22:13:19

MongoDB分片环境下的查询路由的相关文章

在 mongodb 终端环境下写多行 javascript 代码、函数

工作中碰到一个问题,需要把某个 collection 中的某些符合条件的数据取出来,逐行处理其中某些字段.mongodb 终端下支持直接写 js 代码.函数,也可以运行 js 文件.1 首先需要设置 mongo 终端的代码编辑器,不设置的话只能输入一行代码文件,无法处理大段 js 逻辑 进入 mongo 终端后,输入 f={} 回车后,继续输入: edit f 未设置过相关系统变量的会收到如下提示: please define EDITOR as a JavaScript string or a

MongoDB Java环境下的开发

同Mysql.Oracle一样,首先要下载驱动包,下载地址. 打开myeclipse,创建一个java project. 在项目下建立一个lib文件夹,将下载的驱动包放到lib下并build到path下: 然后在src下建一个db.properties文件 host=127.0.0.1 port=27017 dbname=test 新建一个util包,包下新建一个类DBUtil package util; import java.io.IOException; import java.net.U

Mongodb~Linux环境下的部署~服务的部署与自动化

<mongodb在linux上的部署> 事实上redis安装程序挺好,直接帮我们生成了服务,直接可以使用systemctl去启动它,而mongodb在这方面没有那么智能,需要我们去编写自己的服务脚本了,然后把它加到开机自启动里面就可以了,主要的过程分为以下几个步骤: mongodb我安装在了/root/tools目录下 一 配置文件,ANSI,记事本编写,UTF8可能有问题 dbpath=/root/tools/mongodb-linux-x86_64-amazon-3.4.2/db logp

MongoDB 分片集群实战

背景 在如今的互联网环境下,海量数据已随处可见并且还在不断增长,对于如何存储处理海量数据,比较常见的方法有两种: 垂直扩展:通过增加单台服务器的配置,例如使用更强悍的 CPU.更大的内存.更大容量的磁盘,此种方法虽然成本很高,但是实现比较简单,维护起来也比较方便. 水平扩展:通过使用更多配置一般的服务器来共同承担工作负载,此种方法很灵活,可以根据工作负载的大小动态增减服务器的数量,但是实现比较复杂,得有专门的人员来运维. Databases for MongoDB 试用 IBM Cloud 上提

ASP.NET Web API WebHost宿主环境中管道、路由

ASP.NET Web API WebHost宿主环境中管道.路由 前言 上篇中说到ASP.NET Web API框架在SelfHost环境中管道.路由的一个形态,本篇就来说明一下在WebHost环境中ASP.NET Web API框架中的管道.路由又是哪一种形态. ASP.NET Web API路由.管道 ASP.NET Web API 开篇介绍示例 ASP.NET Web API 路由对象介绍 ASP.NET Web API 管道模型 ASP.NET Web API selfhost宿主环境

MongoDB4.0 WINDOWS环境下 副本集、分片部署

部署开始: 创建路径 D:\Program Files\MongoDB\MySet下 config Data log 文件夹 config文件夹下准备配置文件: 分片1的副本集1 storage: dbPath: D:/Program Files/MongoDB/MySet/Data/shard11 journal: enabled: true systemLog: destination: file logAppend: true path: D:/Program Files/MongoDB/

mongodb基础环境部署(windows系统下)

前言:由于项目组需要进行大数据管理分析系统的开发,同时又希望所用的到相关软件和库均为开源,因此项选择使用mongodb这一非关系型,结构组织较为灵活的开源数据库.同时之所以写该文档,主要是认为网上太多杂乱的操作教程和无意义的废话,因此我对整个部署教程进行了整理,在操作步骤部分尽可能少废话. 一.mongodb基本特性 对开发者而言,选择mongodb需要了解其与其他数据库相比较而言的优越特性,由于本文主要介绍mongodb在windows环境下的部署,因此这里只简单介绍几点特性. 1.数据组织灵

MongoDB在Windows下的环境配置和使用(全程图解)

总是觉得配置环境是一个超级麻烦的事情啊,而且网上说的又比较乱,配置完后又没有说怎么开始运行,在哪输入增删改查语句,像突然断层一样.所以就在这里详细说说. 一:下载安装 1.去官网的下载页面 2.下载完后是一个exe安装程序,只要一直按next即可.以前是压缩包的,现在方便了很多,不过默认的安装路径是C:\Program Files\MongoDB(我是固态硬盘,嘻嘻) 二:创建data文件夹,在cmd中设置data路径 1.我直接在MongoDB的bin文件里面设置的data文件夹,数据库里面的

MPLS VPN环境下BGP导入默认路由问题

本次模拟实验的初衷是验证同一个VPN环境下,多个ISP互联时导入默认路由的可行性问题,在模拟实验中触发另外一个问题---关于BGP导入默认路由的方式讨论.(不同的ISP之间跨域互联使用Option A的方式进行互联,实际上相当于一台CE作用,为了方便模拟实际情况,采用AS 50和AS 60来模拟不同的ISP,接入到AS 34中) 实验需求: (1)  同一个VRF之间可以实现互通性: (2)  往不同的VRF导入默认路由时,路由选路的方式 (3)  BGP导入默认的方式总结 拓扑环境描述: 1.