共计 5059 个字符,预计需要花费 13 分钟才能阅读完成。
要在真实环境中实现 MongoDB 分片至少需要四台服务器做分片集群服务器,其中包含两个 Shard 分片副本集(每个包含两个副本节点及一个仲裁节点)、一个配置副本集(三个副本节点,配置不需要仲裁节点),其中 Shard 的副本节点必须拥有单独的服务器,通常一个 Shard 副本集由 3 个以上副本节点组成更好,奇数个副本节点不需要额外配置仲裁节点。因为仲裁节点和配置节点不需要耗费很多的资源,可以与其他进程共享一台服务器。
当然了,对于平时学习而言,配置那么多服务器是不现实的,用 VM 虚拟机也不现实,毕竟 MongoDB 内存开销不小,所以暂时将所有需要的数据库配置在同一台电脑,以不同端口区分,其中包含以下几个数据库
Shard 节点
Shard-a-1 端口 37001
Shard-a-2 端口 37002
Shard-a-3 端口 37003
——————————————————————–
Shard-b-1 端口 37011
Shard-b-2 端口 37012
Shard-b-3 端口 37013
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
更多 MongoDB 相关教程见以下内容:
MongoDB 文档、集合、数据库简介 http://www.linuxidc.com/Linux/2016-12/138529.htm
MongoDB 3 分片部署及故障模拟验证 http://www.linuxidc.com/Linux/2016-12/138529.htm
Linux CentOS 6.5 yum 安装 MongoDB http://www.linuxidc.com/Linux/2016-12/137790.htm
CentOS 7 yum 方式快速安装 MongoDB http://www.linuxidc.com/Linux/2016-11/137679.htm
MongoDB 的查询操作 http://www.linuxidc.com/Linux/2016-10/136581.htm
在 Azure 虚拟机上快速搭建 MongoDB 集群 http://www.linuxidc.com/Linux/2017-09/146778.htm
MongoDB 复制集原理 http://www.linuxidc.com/Linux/2017-09/146670.htm
MongoDB 3.4 远程连接认证失败 http://www.linuxidc.com/Linux/2017-06/145070.htm
Ubuntu 16.04 中安装 MongoDB3.4 数据库系统 http://www.linuxidc.com/Linux/2017-07/145526.htm
MongoDB 权威指南第 2 版 PDF 完整带书签目录 下载见 http://www.linuxidc.com/Linux/2016-12/138253.htm
MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里
本文永久更新链接地址:http://www.linuxidc.com/Linux/2017-12/149904.htm