目录
本文唯一缺憾:
1.MongoDB 3.0 升级 4.0后 新特性
2.集群搭建----Start
2.1 准备工作
2.2 MongoDB 安装
2.3 MongoDB 集群安装
2.3.1 ConfigServer 安装
2.3.2 ShardServer 安装
2.3.2.1 Shard1 Server安装
2.3.2.2 Shard2 Server安装
2.3.2.3 Shard3 Server安装
2.3.3 Mongos Server 安装
2.3.4 MongoDB 6台服务器,副本集混合模式集群搭建完成
2.4 数据分片操作
2.4.1.数据分片步骤
2.4.2 数据分片图解
2.4.2.1 集合为空时,分片图解
2.4.2.2 集合不为空时,分片图解(未成功!!!)
2.5 Primary异常后,Secondary自动切换为 Primary
不解之处:MongoDB现在有3个分片,如果我现在通过 mongos .db.user.insert({name:'xx',age:i}) 存储了20000条数据有用的数据,我看到都到了shard2上。突然我想起来了我需要对user这个集合分片。在不影响数据的情况下,如何将shard2上的数据分到 shard1和shard3 上面。搭建Mongo集群卡在这了,死活搞不懂这块,能给提供意见吗? 如果实现对user表分片,然后查数据,使用hash分散 ,是能够正确分片的。就是前面那种情况搞了很长时间没搞懂。大佬有啥见解能帮助小的我吗?谢谢
1.取消了 M-S 模式集群,只支持 M-A-S 模式集群,但是这种模式也不常用(如下图所示)
2.MongoDB 4.0 重大变动,就是开始支持事务,但是目前不支持跨文档事务(后续4.x版本有望实现跨文档事务)
3.MongoDB集群开发,常用的模式是 副本集集群混合模式开发(如下图所示)
所有的请求都是先达到 Mongos,通过Mongos调度来获取想要的数据
1.MongoDB 4.0.12 下载(请点击:下载)
2.Linux环境:CentOS 6.x
3.MongoDB安装路径:/usr/local/env/mongodb
4.MongoDB集群安装路径:/usr/local/cluster/mongodb
5.虚拟机(6台)
IP分布:192.168.204.201 ~ 192.168.204.206
HA 集群:3台 Mongos Server
3台 Config Server
3个分片 Shar1 Server ~ Shard3 Server。Shard1 ~ Shard3 随机分配到6台服务器上,保证数据的高可用
服务器规划:
192.168.204.201 | 192.168.204.202 | 192.168.204.203 | 192.168.204.204 | 192.168.204.205 | 192.168.204.206 |
Mongos Server | Mongos Server | Mongos Server | Config Server | Config Server | Config Server |
Shard1 Server | Shard2 Server | Shard3 Server | |||
Shard1 Server | Shard2 Server | Shard3 Server | |||
Shard1 Server | Shard2 Server | Shard3 Server |
端口分划分:
Mongos Server :27017
Config Server :27017 (Mongos在201~203服务器,Config 在204~206服务器,所以两个端口号一样不冲突)
Shard1 Server :27027
Shard2 Server :27037
Shard3 Server :27047
你也可以来更多的分片,这个可以自行决定,如下图分配等(为了保证集群的高可用,起码得有3个分片吧)
192.168.204.201 | 192.168.204.202 | 192.168.204.203 | 192.168.204.204 | 192.168.204.205 | 192.168.204.206 |
Mongos Server |
Mongos Server |
Mongos Server |
Config Server |
Config Server |
Config Server |
Shard1 Server |
Shard2 Server |
Shard3 Server |
Shard4 Server |
Shard5 Server |
Shard6 Server |
Shard6 Server |
Shard1 Server |
Shard2 Server | Shard3 Server | Shard4 Server | Shard5 Server |
Shard5 Server |
Shard6 Server | Shard1 Server | Shard2 Server | Shard3 Server | Shard4 Server |
你可以继续添加分片...... 也可以继续添加 Mongos Server...... 继续添加ConfigServer...... 起码保证高可用的奇数台(3台)即可 |
端口分划分:
防火墙问题,线上环境处于安全考虑不建议关闭防火墙,建议开放指定端口。如何开放指定端口,请点击链接参考:Linux开放指定端口。如果你是本地测试,也可以关闭防火墙
集群之间相互通信,需要六台服务器同时开放 27017、270027、27037、27047端口。
scp 命令 免密登录,将 修改后的 iptables 文件发送给集群中的其他5台服务器。开放后切记重启防火墙使其生效
①解压缩 tgz 安装包到指定目录 /usr/local/env/mongodb
命令:tar -zxvf mongodb-linux-x86_64-4.0.12.tgz -C /usr/local/env/
②重命名解压缩后的文件夹
命令:mv mongodb-linux-x86_64-4.0.12 mongodb
③配置环境变量(将MongoDB路径配置到 PATH路径 下)
命令:vi /etc/profile 添加 mongodb/bin 目录到 PATH 下 (根据自己安装目录添加)
配置完成,使用 命令:source /etc/profile 使配置生效
④配置完成,检查是否配置成功
命令:mongo --version 如下图,说明配置成功
⑤六台服务器,都需要执行上面 4 步。你可以使用scp 命令来完成。
scp 命令的使用请参考:Linux命令---scp
使用 scp 命令,嫌输密码麻烦,免密登录的使用,你可以参考:Linux免密登陆设置
新建目录 /usr/local/cluster/mongodb,将MongoDB集群统一安装到该路径下,每台服务器都是该目录。
①根据规划,在204、205、206三台服务器,开始配置 ConfigServer
在204、205、206 三台服务器,新建config目录,在config目录下新建 data、log文件夹(分别用于存放数据相关和日志相关内容)
mkdir -p /usr/local/cluster/mongodb/config/data
mkdir -p /usr/local/cluster/mongodb/config/log 此时3台服务器,均创建 data、log文件夹成功后,开启下一步操作
②在config目录下,添加配置文件 config.conf,内容如下:
必改内容:path、dbPath、pidFilePath、port、bindIp 这5处。replSetName如果修改,则3台必须一起修改,保证config Server集群名称一致。
204服务器:(切记路径配置一定要准确,如果配置错误,则会报 --fork 错误,切记,建议 pwd 复制)
## content
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/config/log/config.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/config/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/config/log/config.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.204
#operationProfiling:
replication:
replSetName: config
sharding:
clusterRole: configsvr
205服务器:(除bindIp选项外,其他与204服务器配置,因为每台服务器路径一致,端口使用也一致)
## content
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/config/log/config.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/config/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/config/log/config.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.205
#operationProfiling:
replication:
replSetName: config
sharding:
clusterRole: configsvr
## content
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/config/log/config.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/config/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/config/log/config.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.206
#operationProfiling:
replication:
replSetName: config
sharding:
clusterRole: configsvr
③使用如下命令,同时启动集群 3 台服务器节点的 ConfigServer
命令:mongod -f /usr/local/cluster/mongodb/config/config.conf
如下图所示,则说明服务启动成功。
④现在三台服务器之间没有任何关系,都是彼此单独运行。怎么才能将他们联系起来呢?
1.连上 Config Server集群 3 台服务器中的任意一台(本文连接 204 服务器)
命令:mongo 192.168.204.204:27017 或者 mongo --host 192.168.204.204 --port 27017
2.切换到 admin 表
命令:use admin
3.执行配置文件(此处的_id就是config.conf配置文件中的replSetName,第二个_id为0、1、2,只要不重复即可,随你定义)
cfg={
_id:"config",members:[
{_id:0,host:'192.168.204.204:27017'},
{_id:1,host:'192.168.204.205:27017'},
{_id:2,host:'192.168.204.206:27017'}
]
}rs.initiate(cfg) --此处成功,会提示 "ok":1,如下图所示
4.此时三台服务便组成了一个集群,通过如下命令可以查看当前集群每个节点的状态
命令:rs.status()
⑤此时,Config Server集群配置完成
①根据规划,在201、203、204三台服务器,分别安装 Shard1 分片及其副本
在201、203、204 三台服务器,新建shard1 目录,然后分别在shard1目录下新建 data、log文件夹(分别用于存放数据相关和日志相关内容)
mkdir -p /usr/local/cluster/mongodb/shard1/data
mkdir -p /usr/local/cluster/mongodb/shard1/log 此时3台服务器,均创建 data、log文件夹成功后,开启下一步操作
②在shard1 目录下,添加配置文件 shard1.conf,内容如下:
必改内容:path、dbPath、pidFilePath、port、bindIp 这5处。replSetName如果修改,则3台必须一起修改,保证shard1分片副本之间名称一致。根据规划,shard1Server端口设置为:27027
201服务器:(切记路径配置一定要准确,如果配置错误,则会报 --fork 错误,切记,建议 pwd 复制)
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/shard1/log/shard1.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/shard1/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 20
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/shard1/log/shard1.pid
# network interfaces
net:
port: 27027
bindIp: 192.168.204.201
#operationProfiling:
replication:
replSetName: shard1
sharding:
clusterRole: shardsvr
203服务器:(除bindIp选项外,其他与201服务器配置,因为每台服务器路径一致,端口使用也一致,均为27027)
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/shard1/log/shard1.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/shard1/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 20
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/shard1/log/shard1.pid
# network interfaces
net:
port: 27027
bindIp: 192.168.204.203
#operationProfiling:
replication:
replSetName: shard1
sharding:
clusterRole: shardsvr
204服务器:(除bindIp选项外,其他与201服务器配置,因为每台服务器路径一致,端口使用也一致,均为27027)
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/shard1/log/shard1.log
# Where and how to store data.
storage:
dbPath: /usr/local/cluster/mongodb/shard1/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 20
# how the process runs
processManagement:
fork: true
pidFilePath: /usr/local/cluster/mongodb/shard1/log/shard1.pid
# network interfaces
net:
port: 27027
bindIp: 192.168.204.204
#operationProfiling:
replication:
replSetName: shard1
sharding:
clusterRole: shardsvr
③使用如下命令,同时启动集群 3 台服务器节点的 ConfigServer
命令:mongod -f /usr/local/cluster/mongodb/shard1/shard1.conf
如下图所示,则说明服务启动成功。
④现在三台服务器之间没有任何关系,都是彼此单独运行。怎么才能将他们联系起来呢?
1.连上 Shard1 Server分片及副本 3 台服务器中的任意一台(本文连接 201 服务器)
命令:mongo 192.168.204.201:27027 或者 mongo --host 192.168.204.201 --port 27027
2.切换到 admin 表
命令:use admin
3.定义副本集配置,并执行配置文件(此处的_id就是config.conf配置文件中的replSetName,第二个_id为0、1、2,只要不重复即可,随你定义)
cfg= {
_id : "shard1",
members : [
{_id : 0, host : "192.168.204.201:27027" },
{_id : 1, host : "192.168.204.203:27027" },
{_id : 2, host : "192.168.204.204:27027" }
]
}rs.initiate(cfg) --此处成功,会提示 "ok":1,如下图所示
4.此时三台服务便组成了一个集群,通过如下命令可以查看当前集群每个节点的状态
命令:rs.status()
⑤此时,Shard1 Server集群配置完成
①根据规划,在202、204、205三台服务器,分别安装 Shard2 分片及其副本
在202、204、205 三台服务器,新建shard2 目录,然后分别在shard2目录下新建 data、log文件夹(分别用于存放数据相关和日志相关内容)
mkdir -p /usr/local/cluster/mongodb/shard2/data
mkdir -p /usr/local/cluster/mongodb/shard2/log 此时3台服务器,均创建 data、log文件夹成功后,开启下一步操作
其他步骤同 2.3.2.1 Shard1 Server 步骤一模一样,
切记以下问题:
①路径问题
②端口问题(Shard2 Server按规定使用 27037)
③conf配置文件中,replSetName 修改为 shard2
④cfg副本集配置内容的修改
①根据规划,在203、205、206三台服务器,分别安装 Shard3 分片及其副本
在203、205、206 三台服务器,新建shard3 目录,然后分别在shard3目录下新建 data、log文件夹(分别用于存放数据相关和日志相关内容)
mkdir -p /usr/local/cluster/mongodb/shard3/data
mkdir -p /usr/local/cluster/mongodb/shard3/log 此时3台服务器,均创建 data、log文件夹成功后,开启下一步操作
其他步骤同 2.3.2.1 Shard1 Server 步骤一模一样,
切记以下问题:
①路径问题
②端口问题(Shard3 Server按规定使用 27047)
③conf配置文件中,replSetName 修改为 shard3
④cfg副本集配置内容的修改
①根据规划,在201、202、203三台服务器,开始配置 Mongos Server
在201、202、203 三台服务器,新建mongos目录,在mongos目录下新建 data、log文件夹(分别用于存放数据相关和日志相关内容)
mkdir -p /usr/local/cluster/mongodb/mongos/data
mkdir -p /usr/local/cluster/mongodb/mongos/log 此时3台服务器,均创建 data、log文件夹成功后,开启下一步操作
②在mongos目录下,添加配置文件 mongos.conf,内容如下:
必改内容:path、pidFilePath、port、bindIp、configDB 这5处。
Mongos端口:根据规划,Mongos端口使用 27017
201服务器:(切记路径配置一定要准确,如果配置错误,则会报 --fork 错误,切记,建议 pwd 复制)
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/mongos/log/mongos.log
processManagement:
fork: true
# pidFilePath: /usr/local/cluster/mongodb/mongos/log/mongos.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.201
#监听的配置服务器, configs为配置服务器的副本集名字
sharding:
configDB: config/192.168.204.204:27017,192.168.204.205:27017,192.168.204.206:27017
202服务器:(除bindIp选项外,其他与201服务器配置,因为每台服务器路径一致,Config Server的地址也一样)
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/mongos/log/mongos.log
processManagement:
fork: true
# pidFilePath: /usr/local/cluster/mongodb/mongos/log/mongos.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.202
#监听的配置服务器, configs为配置服务器的副本集名字
sharding:
configDB: config/192.168.204.204:27017,192.168.204.205:27017,192.168.204.206:27017
203服务器:(除bindIp选项外,其他与201服务器配置,因为每台服务器路径一致,Config Server的地址也一样)
systemLog:
destination: file
logAppend: true
path: /usr/local/cluster/mongodb/mongos/log/mongos.log
processManagement:
fork: true
# pidFilePath: /usr/local/cluster/mongodb/mongos/log/mongos.pid
# network interfaces
net:
port: 27017
bindIp: 192.168.204.203
#监听的配置服务器, configs为配置服务器的副本集名字
sharding:
configDB: config/192.168.204.204:27017,192.168.204.205:27017,192.168.204.206:27017
③使用如下命令,同时启动集群 3 台服务器节点的 Mongos Server
命令:mongos -f /usr/local/cluster/mongodb/mongos/mongos.conf (注意此处是mongos,不是mongod)
如下图所示,则说明服务启动成功。
③连上 Mongos Server 3 台服务器中的任意一台(本文连接 201 服务器,端口号注意是:27017)
命令:mongo 192.168.204.201:27017 或者 mongo --host 192.168.204.201 --port 27017
④切换到 admin 表
命令:use admin
⑤将副本集/切片加入到 Mongos 路由服务器
sh.addShard("shard1/192.168.204.201:27027,192.168.204.203:27027,192.168.204.204:27027")
sh.addShard("shard2/192.168.204.202:27037,192.168.204.204:27037,192.168.204.205:27037")
sh.addShard("shard3/192.168.204.203:27047,192.168.204.205:27047,192.168.204.206:27047")
接下来将完成数据的分片操作
现在面对的情形是:上面集群搭建是完成了,数据部分也配有 Shard1、Shard2、Shard3 三个分片。如果我现在随机模拟写入一些数据,此时数据只存储在当前分片上,而没有进行分片。
分片是指将数据拆分,将其分散存在不同机器上的过程,有时也叫分区。将数据分散在不同的机器上,不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。
MongoDB 默认是不帮我们开启分片的,需要我们手动操作来完成对某个库中的指定(表) 数据的分片。
接下来我们需要完成的就是:集群数据的分片操作。
切记一点:所有的请求都是先打到 Mongos,通过Mongos 调度来获取相关数据内容。我们在 Mongos 路由服务器完成操作,现在切换到 testdb 数据库下,创建 user 表,以 user 表为实例来介绍MongoDB 的数据分片操作。
1.连接到集群中的随意一台 Mongos (本文连接到201服务器,端口为27017)
命令:mongo 192.168.204.201:27017
2.切换到 testdb 数据库
命令:use testdb
3.开启一个数据库的分片功能
命令:sh.enableSharding("testdb")
4.分片时的索引问题
# 如果集合中已经存在数据,在选定作为shard key 的键列必须创建索引;(如何创建索引,参考 步骤 6)
# 如果集合为空,mongodb 将在激活集合分片(sh.shardCollection)时创建索引;
5.开启一个collection(表)的分片功能 (即:指定数据库里需要分片的表)
命令:sh.shardCollection("库名.表名",{"字段",1})
例1:指定 testdb 库中的 user 表,以 _id 字段为 hash散列 进行分片)
命令:sh.shardCollection("testdb.user",{"_id":"hashed"}) -------基于 hash散列 分片(能够实现数据分片)
例2:指定 testdb 库中的 user 表,以 name 字段进行分片)
命令:sh.shardCollection("testdb.user",{"name":1}) ------- 基于 值 分片(不能实现数据的分片)
# 基于 hashed 散列能保证集群中数据的均衡。例1中,通过字段 _id 的散列值进行数据分配。MongoDB计算 _id 字段的散列值作为散列索引,它将提供集群中文档的均匀分布。
# 基于 值 的分片,不能实现集群中数据的分片!!!
6.如何创建索引
参考:MongoDB 索引
例1:为 testdb 库中的 user 表创建索引,以_id 字段升序创建索引
命令:db.user.ensureIndex({_id:1})
例2:也可以创建联合索引(以_id 字段升序,name字段降序创建索引)
命令:db.user.ensureIndex({_id:1,name:-1})
①进行分片的过程
②模拟插入数据的过程
③分别进入 shard1(201服务器)、shard2(202服务器)、shard3(203服务器)查看数据是否分片成功
上图:6 + 11 + 3 = 20条,
正好将20条数据分到 3 个 shard 中(这里 hash 散列 分片,并不是100%平均分配,数据量大后会尽量达到平均分配)
不解之处:MongoDB现在有3个分片,如果我现在通过 mongos .db.user.insert({name:'xx',age:i}) 存储了20000条数据有用的数据,我看到都到了shard2上。突然我想起来了我需要对user这个集合分片。在不影响数据的情况下,如何将shard2上的数据分到 shard1和shard3 上面。搭建Mongo集群卡在这了,死活搞不懂这块,能给提供意见吗? 如果实现对user表分片,然后查数据,使用hash分散 ,是能够正确分片的。就是前面那种情况搞了很长时间没搞懂。大佬有啥见解能帮助小的我吗?谢谢
①mongos操作,使用 testdb 库,向 grade 表中插入 20 条数据
②此时,查看shard1(201服务器)、shard2(202服务器)、shard3(203服务器)分片数据。发现Mongos路由将数据都存储在了 shard2 上
③开始对数据不为空的表 grade ,进行分片(切记:需要创建索引)
备注:grade 表也在 testdb 库下,user 表已对 testdb 库开启分片功能,此处所以不需要再对 testdb 库开启分片功能
1.不创建索引,直接对数据不为空的表开启分片功能,会报如下错误。
2.开始创建索引,并对 grade 表开启分片功能(数据不为空的表,使用 hash 散列索引不会成功,需要针对某个键值升序或降序分片才能成功)
④此时,查看shard1(201服务器)、shard2(202服务器)、shard3(203服务器)分片数据。发现Mongos路由将数据还是都存储在了 shard2 上,没有进行分片(此处失败!!!求大佬解释帮助一下)
本文:shard1 为 Primary,我们手动将 shard1 关闭后,会将 shard2 Secondary 自动 转换 为 Primary提供服务,从而实现了主从之间的来回切换,保证高可用。
MongoDB 4.0.12 集群搭建,至此介绍完毕
如果本文对你有所帮助,那就给我点个赞呗 ^_^
End