上面的(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就是这样来实现海量数据的分布式存储的,同时由于每个片又是由复制集组成,保证了数据的可靠性。

转载于:https://www.cnblogs.com/guoyuanwei/p/3763027.html

mongoDB研究笔记:分片集群的工作机制相关推荐

  1. MongoDB部署分片集群

    MongoDB分片集群简介 在单机环境下,高频率的查询会给服务器 CPU 和 I/O 带来巨大的负担,基于这个原因,MongoDB 提供了分片机制用于解决大数据集的分布式部署,从而提高系统的吞吐量.一 ...

  2. sonar 集群环境工作机制的深入理解

    sonar 集群配置一般是一个master,和几个es 构成的集群环境,而master和es 机器的确定,就是由sonar.properties文件配置确定的. sonar master proper ...

  3. TiDB和MongoDB分片集群架构比较

    此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 最近阅读了TiDB源码的说明文档,跟MongoDB的分片集群做了下简单对比. 首先展示TiDB的整体架构 M ...

  4. MongoDB4.4版本源码部署分片集群

    MongoDB4.4版本源码部署分片集群 node1:39.103.204.27 node2:49.232.197.39 node3:43.138.41.190 shard1 PRIMARY shar ...

  5. 搭建MongoDB分片集群

    在部门服务器搭建MongoDB分片集群,记录整个操作过程,朋友们也可以参考. 计划如下: 用5台机器搭建,IP分别为:192.168.58.5.192.168.58.6.192.168.58.8.19 ...

  6. mongodb分片概念和原理-实战分片集群

    一.分片 分片是一种跨多台机器分发数据的方法.MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作的部署. 问题: 具有大型数据集或高吞吐量应用程序的数据库系统可能会挑战单个服务器的容量.例如 ...

  7. 2021-05-12 MongoDB面试题 什么是MongoDB分片集群

    什么是MongoDB分片集群? Sharding cluster是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建.sharding分片很好的解决了单台服务器磁盘空 ...

  8. 在分片集群中追踪MongoDB的操作日志

    2019独角兽企业重金招聘Python工程师标准>>> 介绍 可追踪游标,特别是追踪MongoDB的操作日志是MongoDB中拥有多种用途.非常受欢迎的特色,例如向数据库发送一个有关 ...

  9. MongoDB集群之分片集群 Shard Cluster

    1.什么是分片 分片(sharding)是MongoDB用来将大型集合水平分割到不同服务器(或者复制集)上所采用的方法.不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载. 2.为什么要分 ...

最新文章

  1. 在代码中获取ApplicationContext实例
  2. Android平台根目录文件
  3. java中File类应用:遍历文件夹下所有文件
  4. 【学习笔记】node.js基础介绍
  5. 微信小程序中显示空格
  6. POJ - 3784 Running Median(动态维护中位数)
  7. 计算机二级 java和web_2020年全国计算机二级WEB程序复习知识点:JavaBean
  8. 3-39客户端(client)写数据到HDFS的流程
  9. 干货 | 设计大佬用的UI手机样机,你要么?
  10. html获取一条一条的li,html – 在一个li中定位一个span
  11. “fatal error C1010”错误解决的三种方法
  12. Windows 7上的Android Studio安装失败,未找到JDK
  13. 蓝桥杯2016年第七届C/C++省赛B组第二题-生日蜡烛
  14. HDFS简单的shell操作--大数据纪录片第二记
  15. FreeSWITCH折腾笔记3——数据库修改为postgresql
  16. 安装Java (JDK16)
  17. f分布表完整图a=0.01_Matlab中的数据分析之概率分布与检验实例讲解
  18. 电流、电压、功率的计算方式
  19. STM32L476 FLASH option bytes
  20. python量化交易策略实例_Python写一个量化股票提醒系统实例

热门文章

  1. Linux 用户管理命令id、su
  2. Mybatis执行select语句无匹配对象时返回集为Empty还是null
  3. simulink中不能改名_《和平精英》没有卡如何解决 改名字方法
  4. 温控窗帘系统制作文档
  5. 空调c语言入门自学视频教程,本人大一,自学c语言,想问一下用哪个编程环境比较好啊?...
  6. thinkphp5基本的一些操作/API友好/获取请求信息(Request)/判断请求类型(GET...)/验证参数数据(Validate)/连接数据库/原生sql语句查询
  7. linux如何捕获9的信号,2018-9-17-bash之信号捕捉
  8. python的对象模型_[ Python 源码剖析] 对象模型概述
  9. Linux虚拟内存管理(glibc)
  10. 如何判断一个类是否是线程安全(可重入)的?