目录
2.3.4 MongoDB 6台服务器,副本集混合模式集群搭建完成
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.MongoDB 3.0 升级 4.0后 新特性
1.取消了 M-S 模式集群,只支持 M-A-S 模式集群,但是这种模式也不常用(如下图所示)
2.MongoDB 4.0 重大变动,就是开始支持事务,但是目前不支持跨文档事务(后续4.x版本有望实现跨文档事务)
3.MongoDB集群开发,常用的模式是 副本集集群混合模式开发(如下图所示)
所有的请求都是先达到 Mongos,通过Mongos调度来获取想要的数据
2.集群搭建----Start
2.1 准备工作
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台服务器。开放后切记重启防火墙使其生效
2.2 MongoDB 安装
①解压缩 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免密登陆设置
2.3 MongoDB 集群安装
新建目录 /usr/local/cluster/mongodb,将MongoDB集群统一安装到该路径下,每台服务器都是该目录。
2.3.1 ConfigServer 安装
①根据规划,在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集群配置完成
2.3.2 ShardServer 安装
2.3.2.1 Shard1 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集群配置完成
2.3.2.2 Shard2 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副本集配置内容的修改
2.3.2.3 Shard3 Server安装
①根据规划,在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副本集配置内容的修改
2.3.3 Mongos Server 安装
①根据规划,在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")
2.3.4 MongoDB 6台服务器,副本集混合模式集群搭建完成
接下来将完成数据的分片操作
2.4 数据分片操作
现在面对的情形是:上面集群搭建是完成了,数据部分也配有 Shard1、Shard2、Shard3 三个分片。如果我现在随机模拟写入一些数据,此时数据只存储在当前分片上,而没有进行分片。
分片是指将数据拆分,将其分散存在不同机器上的过程,有时也叫分区。将数据分散在不同的机器上,不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。
MongoDB 默认是不帮我们开启分片的,需要我们手动操作来完成对某个库中的指定(表) 数据的分片。
接下来我们需要完成的就是:集群数据的分片操作。
切记一点:所有的请求都是先打到 Mongos,通过Mongos 调度来获取相关数据内容。我们在 Mongos 路由服务器完成操作,现在切换到 testdb 数据库下,创建 user 表,以 user 表为实例来介绍MongoDB 的数据分片操作。
2.4.1.数据分片步骤
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})
2.4.2 数据分片图解
2.4.2.1 集合为空时,分片图解
①进行分片的过程
②模拟插入数据的过程
③分别进入 shard1(201服务器)、shard2(202服务器)、shard3(203服务器)查看数据是否分片成功
上图:6 + 11 + 3 = 20条,
正好将20条数据分到 3 个 shard 中(这里 hash 散列 分片,并不是100%平均分配,数据量大后会尽量达到平均分配)
2.4.2.2 集合不为空时,分片图解(未成功!!!)
不解之处: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 上,没有进行分片(此处失败!!!求大佬解释帮助一下)
2.5 Primary异常后,Secondary自动切换为 Primary
本文:shard1 为 Primary,我们手动将 shard1 关闭后,会将 shard2 Secondary 自动 转换 为 Primary提供服务,从而实现了主从之间的来回切换,保证高可用。
MongoDB 4.0.12 集群搭建,至此介绍完毕
如果本文对你有所帮助,那就给我点个赞呗 ^_^
End