MongoDB 3.4 分片 由副本集组成

要在真实环境中实现MongoDB分片至少须要四台服务器作分片集群服务器,其中包含两个Shard分片副本集(每一个包含两个副本节点及一个仲裁节点)、一个配置副本集(三个副本节点,配置不须要仲裁节点),其中Shard的副本节点必须拥有单独的服务器,一般一个Shard副本集由3个以上副本节点组成更好,奇数个副本节点不须要额外配置仲裁节点。由于仲裁节点和配置节点不须要耗费不少的资源,能够与其余进程共享一台服务器。数据库

固然了,对于平时学习而言,配置那么多服务器是不现实的,用VM虚拟机也不现实,毕竟MongoDB内存开销不小,因此暂时将全部须要的数据库配置在同一台电脑,以不一样端口区分,其中包含如下几个数据库服务器

Shard节点app

  Shard-a-1 端口 37001学习

  Shard-a-2 端口 37002spa

  Shard-a-3 端口 370033d

--------------------------------------------------------------------  rest

   Shard-b-1 端口 37011日志

   Shard-b-2 端口 37012code

   Shard-b-3 端口 37013router

 

Config节点

  Config-1 端口 41001

  Config-2 端口 41002

  Config-3 端口 41003

 

Router节点

  Router 端口 50000

文件目录大概以下,其中router中的config改成 mongos.cfg

其中Shard节点和Config节点和开启普通MongoDB数据库同样,用Mongod启动,在Windows下不能使用 fork参数后台化,我的更推荐使用Service来托管

其中Shard节点的配置以下,每一个文件夹下对应的配置把dbpath/logpath/replSet(shard-a和shard-b)改掉,由于要开启多个db因此httpinterface设置为false,不开启监听,不然每一个db都会对应多一个端口号+1000的监听端口,37002的监听端口为38002 

dbpath=D:\mongodatas\shard-a2\data
logpath=D:\mongodatas\shard-a2\log\mongod.log
logappend=true
directoryperdb=true
rest=true
httpinterface=false
port=37002
shardsvr=true
replSet=shard-a

Config节点的配置以下,与shard节点的区别就是shardsvr换成了configsvr,配置服务器是不会开启监听端口的

dbpath=D:\mongodatas\config1\data
logpath=D:\mongodatas\config1\log\mongod.log
logappend=true
directoryperdb=true
rest=true
port=41001
configsvr=true
replSet=configset

接下来以托管到Service的方式启动全部的Shard节点和Config节点,如下只是启动其中一个,一共有九个(shard-a有3个,shard-b有3个,config有3个),在命令提示符(管理员) 的窗口执行,普通权限会报错的,下文用到Service的同样

sc create MongoShardA1 binPath= "C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe --config=D:\mongodatas\shard-a1\mongod.cfg --service"
net start MongoShardA1

使用命令  services.msc打开服务窗口查看服务是否开启或者使用 netstat -nao指令查端口是否开启,若是全都正常开启,则开始配置Shard副本集

任意链接shard-a中服务器 (37001/37002/37003)打开MongoDB Shell

mongo --port 37001

对副本集进行初始化,若是对rs方法不熟悉,可使用rs.help()显示帮助文档

rs.initiate()

此时发现37001端口的命令输入已经成为了副本集的形式,接下来添加另外两个成员,一个副本节点,一个仲裁节点

rs.add("localhost:37002")
rs.add("localhost:37003",{arbiterOnly:true})

最好使用本机的内网地址,而不是使用localhost或者127.0.0.1

 接下来查看副本集是否运行正常

rs.status()

退出现有MongoDB Shell或者开启新的CMD进入Shard-b中任意服务器对Shard-b副本集进行初始化,进入Config副本集任意服务器对Config副本集进行初始化,注意Config副本集进行初始化的时候不须要指定仲裁节点

以上全部操做,对Config副本集进行初始化很是重要,网上有不少示例都没有对Config副本集进行初始化,会致使mongos服务没法开启,链接不上router服务器

如今开始配置router的配置mongos.cfg

configdb=configset/DESKTOP-4NVUAKK:41001,192.168.20.229:41002,192.168.20.229:41003
logpath=D:\mongodatas\router\log\mongod.log
logappend=true
port=50000

注意configdb的配置,新版本里面采用 replSet/hsot:port,host:port的形式,其中host必须采用config副本集里面rs.status()出来的members中的name,不然会执行失败,若是configdb中的副本集没有执行初始化设定Primary ,此时用Service是没法启动成功的,可是用指令启动会给人一种启动成功的假象,查看router对应的日志会发现一只在尝试链接Config副本集: No primary detected for set configset,此时查看任务管理器会发现有mongos的进程,查看端口会发现router的端口并未打开 

 

以托管到Service的方式开始Router服务

sc create MongoRouter binPath= "C:\Program Files\MongoDB\Server\3.4\bin\mongos.exe --config=D:\mongodatas\shard-a1\mongos.cfg --service"
net start MongoRouter

注意上面的执行程序是mongos而不是mongod 配置文件名不要弄错了

正常启动Router服务器以后,链接到router数据库的MongoDB Shell

mongo --port 50000

开始为router指定分片副本集,具体操做如截图所示

sh.addShard("replSet/host:port,host:port")

注意不要使用localhost或者127.0.0.1,不然会报错

使用与副本集Members里面name不一致的host也是会报错的

正常状况下添加成功以下

查看数据库config中的shards集合

db.getSiblingDB("config").shards.find() 或者 db.runCommand({listshards:1})

 到如今为止,分片环境已经搭建成功,但要引用到数据库和文档上,还须要对数据库和文档进行分片

 

 

 开启一个数据库上的分片,这是对任何集合进行分片的先决条件

sh.enableSharding("dbName") 

完成以后去config里查看是否分片

db.getSiblingDB("config").databases.find()

 

对数据库上的某个集合进行分片,要定义一个分片键,可使用组合分片建,像我使用的是author和_id的组合,若是是对现有集合进行分片,必须在运行shardcollection命令前建立一个与分片键对应的索引

sh.shardCollection("dbName.collectionName",{key1:1,key2:1})

db.getSiblingDB("config").collections.find()

 

对空集合进行、分片时 MongoDB会字每一个分片上建立一个与分片键对应的索引,能够直接链接分片,用getIndexes()验证,此时数据量还没达到分片标准啊,分片shard-a副本集尚未建立books

 

用客户端链接router服务器(和链接普通服务器同样)插入大量数据,调用sh.status()能够看到分配到两个shard上保存了

db.chunks.count("shard","shard-a")

db.chunks.count("shard","shard-b")

 

查看拆分次数

db.changelog.count({what:"split"}) 

查看迁移次数

db.changelog.find({what:"moveChunk.commit"}).count()

 

能够经过db.books.find(****).explain() 查看执行计划

若是查询条件包含分片键,则能很快找到对应分区 针对性查询,不然将遍历全部分区 全局/分散/汇集查询

 

db.books.ensureIndex({title:1}) 在title上建立索引

 

每一个分片都维护本身的索引,每一个分片上的分片集合都应该拥有相同的索引

分片集合只容许在_id字段和分片键上添加惟一索引

分片键是不能够修改的,不要使用升序分片键,粒度不能太细(如照片就不该该按md5分,而应该按所属人分)

 

副本集的每一个成员都应该在一个单独的服务器上,用于复制的成员要有本身的机器,

仲裁节点和配置节点能够与其余进程共享主机,但须要部署在不一样服务器

少数大分片比大量小分片好

 

手动块拆分

sh.splitAt("dbname.collectionName",{key,value,key:value}) 根据key分块  value是数据库中的值,根据这个值拆分红两块

sh.moveChunk("dbname.collectionName",{key,value},"shardB") 将包含key为value的文档移动到分片B

相关文章
相关标签/搜索