当前位置: 首页 > news >正文

初识MongoDB分片

分片是指将数据拆分,拆分后存放在不同的机器上的过程,以此来降低单个服务器的压力,同时也解决单个服务器硬盘空间不足的问题,让我们可以用廉价的机器实现高性能的数据架构。有的小伙伴不理解分片和副本集的差异,一言以蔽之:副本集上每个备份节点存储的数据都是相同的,分片上存储的数据则是不同的。好了,本文我们就先来看看分片环境的搭建。

本文是MongoDB系列的第十八篇文章,了解前面的文章有助于更好的理解本文:


1.Linux上安装MongoDB
2.MongoDB基本操作
3.MongoDB数据类型
4.MongoDB文档更新操作
5.MongoDB文档查询操作(一)
6.MongoDB文档查询操作(二)
7.MongoDB文档查询操作(三)
8.MongoDB查看执行计划
9.初识MongoDB中的索引
10.MongoDB中各种类型的索引
11.MongoDB固定集合
12.MongoDB管道操作符(一)
13.MongoDB管道操作符(二)
14.MongoDB中MapReduce使用
15.MongoDB副本集搭建
16.MongoDB副本集配置
17.MongoDB副本集其他细节


环境准备

准备三台已经装好了MongoDB的服务器,地址分别是:

192.168.248.128
192.168.248.135
192.168.248.136

本文使用的MongoDB版本为3.4.9

规划

首先我们需要三台配置服务器,配置服务器相当于集群的大脑,配置服务器中保存着集群和分片的元数据,即每个分片都包含了哪些数据信息,这些数据都是保存在配置服务器中的,我这里将开启三个配置服务器实例,这三个配置服务器将运行在三个MongoDB服务器上,地址分别如下:

192.168.248.128:20000
192.168.248.135:20000
192.168.248.136:20000

接下来需要一个Mongos实例,Mongos对请求进行路由,Mongos扮演的角色有点类似于一个门面,我们以后访问的时候,直接访问Mongos即可,再由Mongos将请求路由到不同的分片上去,Mongos在启动时会去访问配置服务器,它将从配置服务器中获取数据的存储信息,Mongos我将启动在如下服务器上:  

192.168.248.128:30000

最后需要三个分片实例,三个分片依然运行在三台服务器上,如下:

192.168.248.128:27017
192.168.248.135:27017
192.168.248.136:27017

搭建配置服务器

配置服务器中不需要太多的空间和资源,因为配置服务器上保存的只是数据的分布表,不保存具体的数据,具体的数据都保存在分片上,配置服务器中1KB的空间约为200MB的真实数据。注意,从MongoDB3.4开始,配置服务器要做成集群的方式。

由于配置服务器是独立的mongod进程,所以我们可以像启动普通的MongoDB服务一样启动配置服务器,只是这里的配置不同罢了。

我这里以192.168.248.128服务器为例来讲述配置服务器的配置启动,另外两台服务器如法炮制即可:

1.在mongodb解压目录下创建db20000文件夹,用来存储配置服务器中的数据。
2.复制一份mongodb.conf,命名为mongodb20000.conf,修改文件内容如下:

dbpath=/opt/mongodb/db20000
logpath=/opt/mongodb/logs/mongodb20000.log
port=20000
fork=true
configsvr=true
replSet=rs

注意dbpath改为我们第一步创建的目录,端口号改为20000(这个随意,只要该端口没被占用即可),configsvr表示这是一个配置服务器,另外由于我们的配置服务器要做成备份集,所以要设置replSet。

3.做好前两步之后,执行如下命令启动配置服务器:

mongod -f /opt/mongodb/bin/mongodb20000.conf

最后,在另外两台服务器上重复上面三个步骤。

三台服务器上都启动成功之后,参考我们之前的[MongoDB副本集搭建]()一文,将这三台配置服务器配成一个副本集,副本集的配置我这里就不再赘述。

搭建Mongos

Mongos实例我们可以启动在任意一台服务器上,我这里就启动在192.168.248.128上,Mongos的配置步骤如下:

1.复制一份mongodb.conf,命名为mongos.conf,修改内容:

logpath=/opt/mongodb/logs/mongos.log
port=30000
fork=true
configdb=rs/192.168.248.128:20000,192.168.248.135:20000,192.168.248.136:20000

因为mongos中不需要保存数据,所以不需要dbpath,端口号改为30000,configdb表示三个配置服务器的地址,注意最前面的rs表示配置服务器副本集的名称。

2.配置完成后,执行如下命令启动mongos:

mongos -f /opt/mongodb/bin/mongos.conf

搭建三个分片

三个分片实际上就是三个普通的MongoDB服务器,给大家看下我的配置文件:

dbpath=/opt/mongodb/db
logpath=/opt/mongodb/logs/mongodb.log
port=27017
fork=true
shardsvr=true

注意多了个shardsvr表示这是一个分片服务器。
然后在三台服务器上分别执行如下命令启动分片:

mongod -f /opt/mongodb/bin/mongodb.conf

添加分片

上面三个步骤完成之后,我们就进入到mongos的shell命令行了,如下:

mongo --port=30000

然后我们可以通过如下命令查看一下分片的当前状态:

sh.status()

执行结果如下(部分):

--- Sharding Status ---
  sharding version: {
}
  shards:
  databases:

shards表示分片服务器,目前还没有,databases表示分片的库,目前也还没有,接下来我们通过如下命令添加分片服务器:

sh.addShard("192.168.248.128:27017")
sh.addShard("192.168.248.135:27017")
sh.addShard("192.168.248.136:27017")

添加三个分片服务器,然后再执行sh.status(),结果如下(部分):

--- Sharding Status ---
  sharding version: {
}
  shards:
        {  "_id" : "shard0000",  "host" : "192.168.248.128:27017",  "state" : 1 }
        {  "_id" : "shard0001",  "host" : "192.168.248.135:27017",  "state" : 1 }
        {  "_id" : "shard0002",  "host" : "192.168.248.136:27017",  "state" : 1 }
  databases:
        {  "_id" : "test",  "primary" : "shard0000",  "partitioned" : false }

设置集合分片

接下来我们来设置集合的分片,首先执行如下命令表示给某个数据库分片:

sh.enableSharding("sang")

对集合分片时,需要选择一个片键,片键实际上就是集合中的一个键,MongoDB将根据这个片键来拆分数据,我们需要先对片键建立索引,如下:

db.c1.ensureIndex({x:1})

然后以x为片键,对c1集合进行分片,如下:

sh.shardCollection("sang.c1",{x:1})

做完这些之后,再执行sh.status()命令,查看目前状态,结果如下(部分):

--- Sharding Status ---
  sharding version: {
}
  shards:
        {  "_id" : "shard0000",  "host" : "192.168.248.128:27017",  "state" : 1 }
        {  "_id" : "shard0001",  "host" : "192.168.248.135:27017",  "state" : 1 }
        {  "_id" : "shard0002",  "host" : "192.168.248.136:27017",  "state" : 1 }
  databases:
        {  "_id" : "test",  "primary" : "shard0000",  "partitioned" : false }
        {  "_id" : "sang",  "primary" : "shard0001",  "partitioned" : true }
                sang.c1
                        shard key: { "x" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard0001       1
                        { "x" : { "$minKey" : 1 } } -->> { "x" : { "$maxKey" : 1 } } on : shard0001 Timestamp(1, 0)

做完上面这些之后,我们再做两个操作:

1.设置自动分片:

sh.setBalancerState(true)

2.设置chunksize,chunksize这一项是用来指定chunk的大小的,为了方便测试分片效果,我们把chunksize指定为1MB,即当这个分片中插入的数据大于1M时开始进行数据分片

db.settings.save({_id:"chunksize",value:1})

OK,做好这些之后,大功告成。

测试

测试方式很简单,我们直接在mongos的命令行向sang的c1集合中插入50000条数据,然后再查看这些数据的分布,就知道分片有没有成功了:

for(var i=0;i<50000;i++){db.c1.insert({x:Math.random()*1000000,name:"hahah"+i})}

然后执行db.c1.stats(),结果如下:

{
"sharded" : true,
"capped" : false,
"ns" : "sang.c1",
"count" : 50000,
"size" : 2688890,
"storageSize" : 1781760,
"totalIndexSize" : 1978368,
"avgObjSize" : 53,
"nindexes" : 2,
"nchunks" : 5,
"shards" : {
        "shard0000" : {
                "ns" : "sang.c1",
                "size" : 926504,
                "count" : 17229,
                "avgObjSize" : 53,
                "storageSize" : 462848,
                "capped" : false,
                "nindexes" : 2,
                "totalIndexSize" : 516096,
                "indexSizes" : {
                        "_id_" : 184320,
                        "x_1" : 331776
                },
                "ok" : 1
        },
        "shard0001" : {
                "ns" : "sang.c1",
                "size" : 392593,
                "count" : 7299,
                "avgObjSize" : 53,
                "storageSize" : 667648,
                "capped" : false,
                "nindexes" : 2,
                "totalIndexSize" : 737280,
                "indexSizes" : {
                        "_id_" : 253952,
                        "x_1" : 483328
                },
                "ok" : 1
        },
        "shard0002" : {
                "ns" : "sang.c1",
                "size" : 1369793,
                "count" : 25472,
                "avgObjSize" : 53,
                "storageSize" : 651264,
                "capped" : false,
                "nindexes" : 2,
                "totalIndexSize" : 724992,
                "indexSizes" : {
                        "_id_" : 237568,
                        "x_1" : 487424
                },
                "ok" : 1
        }
}
}

OK,看到如上结果,说明我们的数据已经分布在三个分片服务器中了。

好了,MongoDB中分片环境的搭建我们就先说到这里,小伙伴们有问题欢迎留言讨论。

参考资料:

1.《MongoDB权威指南第2版》

更多资料请关注公众号:

图片描述

相关文章:

  • BZOJ 2821 作诗(Poetize)(分块)
  • python学习笔记(九):操作数据库
  • Java今年最流行的三大框架你应该学习了
  • JSON数组,JSON对象,数组的区别与基本操作整理
  • 阿里云全球19个地域节点,哪个节点的服务器好,速度快?
  • 回顾2017:基础设施支出增长 思科占主导地位
  • 微服务入门【系列视频课程】
  • mongodb集群模式(主从模式,副本集模式,分片模式)
  • 透彻影像王书浩:三易其辙与功不唐捐
  • 如何使用 Spinnaker 和 Kubernetes 进行数据库变更发布
  • 为什么需要模版成员方法
  • W3C官方推荐使用新发布的HTML5.2
  • Lintcode: Minimum Subarray 解题报告
  • laravel ORM get() first()
  • h5 扫描二维码打开app和点击下载功能的实现
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【翻译】babel对TC39装饰器草案的实现
  • Apache Pulsar 2.1 重磅发布
  • Babel配置的不完全指南
  • ECMAScript 6 学习之路 ( 四 ) String 字符串扩展
  • GitUp, 你不可错过的秀外慧中的git工具
  • Nodejs和JavaWeb协助开发
  • node和express搭建代理服务器(源码)
  • Python 基础起步 (十) 什么叫函数?
  • Web标准制定过程
  • WinRAR存在严重的安全漏洞影响5亿用户
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 飞驰在Mesos的涡轮引擎上
  • 看域名解析域名安全对SEO的影响
  • 来,膜拜下android roadmap,强大的执行力
  • 系统认识JavaScript正则表达式
  • 追踪解析 FutureTask 源码
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • C# - 为值类型重定义相等性
  • 阿里云服务器如何修改远程端口?
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • #中的引用型是什么意识_Java中四种引用有什么区别以及应用场景
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (4)logging(日志模块)
  • (LNMP) How To Install Linux, nginx, MySQL, PHP
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (附源码)ssm高校实验室 毕业设计 800008
  • (附源码)ssm考生评分系统 毕业设计 071114
  • (黑马C++)L06 重载与继承
  • (六)软件测试分工
  • (学习日记)2024.01.19
  • (转载)从 Java 代码到 Java 堆
  • .NET CF命令行调试器MDbg入门(二) 设备模拟器
  • .NET Core使用NPOI导出复杂,美观的Excel详解
  • .net framework4与其client profile版本的区别
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .Net Memory Profiler的使用举例
  • .NET Remoting Basic(10)-创建不同宿主的客户端与服务器端