mongoDB研究笔记:分片集群的工作机制
上面的(http://www.cnblogs.com/guoyuanwei/p/3565088.html)介绍了部署了一个默认的分片集群,对mongoDB的分片集群有了大概的认识,到目前为止我们还没有在集群上建立其它数据库,mongoDB的分片是基于集合(表)来进行的,因此要对一个集合分片,必须先使其所在的数据库支持分片。如何使一个集合分片?如何选择分片用到的片键?平衡器如何使chunks块在片中迁移?分片的读写情况怎么样?接下来将探讨这些问题。
使集合分片
(1)连接到上面所配置集群中的mongos实例
> mongo --port 40009
(2)在集群中创建数据库eshop和集合users
mongos> use eshop
switched to db eshop
mongos> db.users.insert({userid:1,username:"lili",city:"beijing"})
此时在集合users中只有一条记录:
{ "_id" : ObjectId("521dcce715ce3967f964c00b"), "userid" : 1, "username" : "lili", "city" : "beijing" }
观察集群的状态信息,字段databases会增加一条记录,其它字段与初始化的集群信息相同:
mongos> sh.status()
databases:
{ "_id" : "eshop", "partitioned" : false, "primary" : "rs0" }
可以看到此时数据库eshop还没支持分片,且数据库中所有未分片的集合将保存在片rs0中;通过查看磁盘上的数据文件,此时会产生eshop.0、eshop.1、eshop.ns三个文件且位于rs0所对应的数据目录中,集群中chunks集合为空,因为现在还没有对集合users分片。
(3)分片
mongoDB的分片是基于范围的,也就是说任何一个文档一定位于指定片键的某个范围内,一旦片键选择好后,chunks就会按照片键来将一部分documents从逻辑上组合在一起。这里对users集合选择"city"字段作为片键来分片,假如现在"city"字段值有"beijing"、"guangzhou"、"changsha",初始的时候随机的向集群中插入包含以上字段值的文档,此时由于chunks的大小未达到默认的阈值64MB或100000个文档,集群中应该只有一个chunk,随着继续插入文档,超过阈值的chunk会被分割成两个chunks,最终的chunks和片键分布可能如下表格所示。表格只是大体上描述了分片的情况,实际可能有所变化,其中-∞表示所有键值小于"beijing"的文档,∞表示所有键值大于"guangzhou"的文档。这里还要强调一点就是chunks所包含的文档,并不是物理上的包含,它是一种逻辑包含,它只表示带有片键的文档会落在哪个范围内,而这个范围的文档对应的chunk位于哪个片是可以查询到的,后续的读写操作就定位到这个片上的具体集合中进行。
开始键值 |
结束键值 |
所在分片 |
-∞ |
beijing |
rs0 |
beijing |
changsha |
rs1 |
changsha |
guangzhou |
rs0 |
guangzhou |
∞ |
rs1 |
下面继续通过命令使集合users分片,使集合分片必须先使其所在的数据库支持分片,如下:
mongos> sh.enableSharding("eshop") //使数据库支持分片
对已有数据的集合进行分片,必须先在所选择的片键上创建一个索引,如果集合初始时没有任何数据,则mongoDB会自动在所选择的的片键上创建一个索引。
mongos> db.users.ensureIndex({city:1}) //创建基于片键的索引
mongos> sh.shardCollection("eshop.users",{city:1}) //使集合分片
成功执行上面命令后,再次查看集群状态信息:
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 3,
"minCompatibleVersion" : 3,
"currentVersion" : 4,
"clusterId" : ObjectId("521b11e0a663075416070c04")
}
shards:
{ "_id" : "rs0", "host" : "rs0/GUO:40000,GUO:40001" }
{ "_id" : "rs1", "host" : "rs1/GUO:40003,GUO:40004" }
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "eshop", "partitioned" : true, "primary" : "rs0" } //数据库已支持分片
eshop.users //分片的集合
shard key: { "city" : 1 } //片键
chunks: //所有块信息
rs0 1 //当前只有1个块在片rs0上
{ "city" : { "$minKey" : 1 } } -->> { "city" : { "$maxKe
y" : 1 } } on : rs0 { "t" : 1, "i" : 0 } //此块的包含键值范围是-∞到∞,且在片rs0上,因为此时集合中只有一条记录,还未进行块的分割、迁移
(4)继续插入数据使集合自动分片
为了观察到集合被分成多个chunk,并分布在多个片上,继续插入一些数据进行分析。
> for(var i = 1; i<10000;i++) db.users.insert({userid:i,username:"lili"+i,city:"beijing"})
> for(var i = 0; i<10000;i++) db.users.insert({userid:i,username:"xiaoming"+i,city:"changsha"})
> for(var i = 0; i<10000;i++) db.users.insert({userid:i,username:"xiaoqiang"+i,city:"guangzhou"})
通过以上三次循环插入文档后,第一个chunk的大小会超过64MB时,出现chunk分割与迁移的过程。再次观察集群的状态信息,字段databases值变为:
databases:
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "eshop", "partitioned" : true, "primary" : "rs0" }
eshop.users
shard key: { "city" : 1 }
chunks:
rs1 1
rs0 2
{ "city" : { "$minKey" : 1 } } -->> { "city" : "beijing"
} on : rs1 { "t" : 2, "i" : 0 } //块区间
{ "city" : "beijing" } -->> { "city" : "guangzhou" } on
: rs0 { "t" : 2, "i" : 1 } //块区间
{ "city" : "guangzhou" } -->> { "city" : { "$maxKey" : 1
} } on : rs0 { "t" : 1, "i" : 4 } //块区间
说明此时集群中有三个块,其中在片rs0上有两个块,在片rs1上有一个块,每个块包含一定区间范围的文档。为了更加清楚的知道这些块是如何分割和迁移的,可以查看changelog集合中的记录信息进行分析。
从命令db.changelog.find()输出内容中可以看到有以下几步:
第一步:分割大于64MB的块,原来此块的片键的区间范围是-∞到∞,分割后区间变为-∞到"beijing"、"beijing"到∞两个区间。
第二步:随着继续插入文档,区间"beijing"到∞所包含的块的大小超过64MB,此时这个区间又被分割为"beijing"到"guangzhou"、"guangzhou"到∞这两个区间。
第三步:经过上面的分割,现在相当于有三个区间块了,这一步做的就是将区间-∞到"beijing"对应的chunk从片rs0迁移到片rs1,最终结果是分片rs0上包含"beijing"到"guangzhou"、"guangzhou"到∞两个区间的块,分片rs1上包含区间-∞到"beijing"的块。
上面循环插入文档时还插入了片键值为"changsha"的记录,这个片键的记录应该都位于区间"beijing"到"guangzhou"所对应的chunk上,只不过由于chunk的大小还未达到64MB,所以还未进行分割,如果继续插入此片键的文档,区间可能会被分割为"beijing"到"changsha"、"changsha"到"guangzhou"这两个区间块。依次类推,mongoDB就是这样来实现海量数据的分布式存储的,同时由于每个片又是由复制集组成,保证了数据的可靠性。
mongoDB研究笔记:分片集群的工作机制的更多相关文章
- 【MongoDB】在windows平台下mongodb的分片集群(五)
本篇接着上面的四篇继续讲述在window平台下mongodb的分片集群搭建. 在分片集群中也照样能够创建索引,创建索引的方式与在单独数据库中创建索引的方式一样.因此这不再多说.本篇主要聚焦在分片键的选 ...
- MongoDB之分片集群(Sharding)
MongoDB之分片集群(Sharding) 一.基本概念 分片(sharding)是一个通过多台机器分配数据的方法.MongoDB使用分片支持大数据集和高吞吐量的操作.大数据集和高吞吐量的数据库系统 ...
- MongoDB之分片集群与复制集
分片集群 1.1.概念 分片集群是将数据存储在多台机器上的操作,主要由查询路由mongos.分片.配置服务器组成. ●查询路由根据配置服务器上的元数据将请求分发到相应的分片上,本身不存储集群的元数据, ...
- MongoDB笔记: 分片集群
MongoDB分片集群由三个模块组成 shard: 分片(或者分区)模块, 每个分片分别存储一部分数据, 从MongoDB 3.6开始, 分片必须是replica set(副本集) mongos: m ...
- MongoDB 搭建分片集群
在MongoDB(版本 3.2.9)中,分片是指将collection分散存储到不同的Server中,每个Server只存储collection的一部分,服务分片的所有服务器组成分片集群.分片集群(S ...
- 【MongoDB】在windows平台下搭建mongodb的分片集群(二)
在上一片博客中我们讲了Mongodb数据库中分片集群的主要原理. 在本篇博客中我们主要讲描写叙述分片集群的搭建过程.配置分片集群主要有两个步骤.第一启动全部须要的mongod和mongos进程. 第二 ...
- 【MongoDB】在windows平台下mongodb的分片集群(六)
在本篇博客中我们主要讨论下博客的管理.因为已经在前面五篇中写了具体的实例,因此这里就不再举例说明. 一.监控 分片集群是整个体系中比較复杂的一块,因此更应该须要监控. 主要命令: serverstat ...
- MongoDB的分片集群搭建
MongoDB的最为自豪的一个特色之一,分片. 参考官方文档: https://docs.mongodb.com/manual/sharding/ 单机压力,高频查询CPU,IO 单表压力,百万千万 ...
- MongoDB 分片集群技术
在了解分片集群之前,务必要先了解复制集技术! 1.1 MongoDB复制集简介 一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合.复制集提供了数据冗余和高等级的可靠性,这 ...
随机推荐
- JAVA可移植性广泛应用
一.JAVA作为一种编程语言:源代码可移植性 作为一种编程语言,JAVA提供了一种最简单同时也是人们最熟悉的可移植性–源代码移植.这意味着任意一个JAVA程序,不论它运行在何种CPU.操作系统或JAV ...
- iOSDate时间格式(转)
在开发iOS程序时,有时候需要将时间格式调整成自己希望的格式,这个时候我们可以用NSDateFormatter类来处理.例如: //实例化一个NSDateFormatter对象 NSDateForma ...
- 使用swfobject.js时样式及传参的问题
swfobject.js 最近需要在项目中引入swf文件. 最初的写法: <div id="recorderDiv"> <object id="reco ...
- win7 部署WCF遇到的问题记录
1. IIS7 handler Mappings默认没有*.svc 的处理,需要安装(页面错误提示好像会提示缺少相应的处理器,记不清楚了) 方法:使用 ServiceModelReg.exe 工具 路 ...
- 一个login
login 1.获取提交表单,保存到变量中.2.判断用户密码是否正确,利用Model类.3.验证用户是否激活.3.判断用户是否记住登录状态,是的话,将其用cookie和session分别保存.没有的话 ...
- 使用Sublime Text3开发AngularJs
之前的Sublime环境安装插件弄得有点乱,卸载了重新安装: 1. 安装sublime: https://www.sublimetext.com/3 2. 注册: —– BEGIN LICENSE — ...
- R与Java
对于从未接触代码的我,看到这些很陌生,现在需要做的是用r语言去做数据处理分析,将分析的结果给Java,然后在Java上输出想要的结果,没人给予指导,自己就这样瞎摸索,真希望有这方面的牛人给予指导,让一 ...
- 自己对Extjs的Xtemplate的忽略
之前学习extjs Xtmeplate受一些书籍的误导,说Xtemplate不支持else ,今天仔细看了官网的示例,才恍然大悟,卧槽!不仅支持if-elseif-else结构 连switch都能够支 ...
- 原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))
场景: 客户端初始化正常,到IIS服务就报80040154. System.Web.Services.Protocols.SoapException: System.Web.Services.Prot ...
- java8 ArrayList源码阅读
转载自 java8 ArrayList源码阅读 本文基于jdk1.8 JavaCollection库中有三类:List,Queue,Set 其中List,有三个子实现类:ArrayList,Vecto ...