第九节我们对MongoDB部署方式进行了梳理,至此已经知道MongoDB部署方式有单机、主从、副本集和分片这几种。
这节我们主要介绍副本集和分片两种方式的部署。因为他两都是基于单机进行扩展的,所以需要了解单机如何部署,关于单机部署可参考《二、MongoDB 及工具的安装》
一、副本集部署
副本集部署是基于单机部署的,所以我们直接在单机部署的基础上进行修改。
首先,是配置文件的修改
#数据库文件位置
dbpath=/app/mongodb/data
#日志文件位置
logpath=/app/mongodb/logs/mongodb.log
# 以追加方式写入日志
logappend=true
# 是否以守护进程方式运行
fork=true
#绑定客户端访问的ip 0.0.0.0 不绑定ip
# bind_ip=192.168.11.xx1,192.168.11.xx2
bind_ip=0.0.0.0
# 默认端口27017
port=27017
####################### 其他配置
# 指定保存mongod进程id;可加可不加;加了之后进程号固定,对于排查问题可以比较方便些
pidfilepath=/app/mongodb/mongo.pid
# 可以配置的MongoDB将数据存储在不同的磁盘设备上,以提高写入吞吐量或磁盘容量。默认为false。
# directoryperdb=true
# 启动密码
# auth=true
# 使用keyfile认证,副本集中的每个mongod实例使用keyfile内容作为认证其他成员的共享密码。只有有正确的keyfile的mongod实例可以加入副本集
#keyFile =/app/mongodb/keyfile
####################### 副本集
# 副本集名称
replSet=lcmongo
说明, 跟单机配置的差别只是多了一个replSet=lcmongo, 这个是作为集群的名称,可自定义。auth 和 keyFile 是用于配置账号权限的,这个不影响集群的搭建,因此去掉先不开启,但是系统安全是很重要的。
我们用三台服务器来演示,分别是
192.168.11.20
192.168.11.21
192.168.11.23
将20这台部署完,复制到另外两台(21和23)。这两台除了要配置MongoDB的环境变量,其他的都不用操作。
我这边以20这台作为主机,21和23为从机。
三台的MongoDB服务都启动。然后在20这台执行客户端命令:
mongo
1、执行初始化命令,这个只需要在主机执行即可
rs.initiate()
2、查看配置信息
rs.conf()
3、添加另外两个从机
rs.add("192.168.11.21:27017")
rs.add("192.168.11.23:27017")
在添加从机时,从机服务必须启动,不然会连接不上。如果有端口需要例外,或者关闭防火墙(不建议)。
4、查看状态
rs.status()
发现当前服务器是 SECONDARY,而不是PRIMARY。因此,需要将它改成PRIMARY。
5、指定PRIMARY
cfg=rs.conf()
cfg.members[0].priority = 2 # 该值越大,优先级越高,取值范围 [0,100], 如果设置为0,那么永远也不会成为主机
rs.reconfig(cfg) # 重置配置,使上面配置生效
如果当前这台机器不是PRIMARY的话, 那么在重置配置时,会报错:
replSetReconfig should only be run on PRIMARY, use the "force" argument to override
让我们强制更新配置
rs.reconfig(cfg, {force:true}) # 强制重置配置
隔个半分钟左右,我们在执行rs.status(),会发现此时的stateStr已经变成PRIMARY了。主机修改到此结束。
6、紧接着,我们需要修改下21和23的配置
分别进入客户端,执行:
db.getMongo().setSecondaryOk()
如果没有意外的话,副本集部署搭建已完成。
我们验证以下两个问题
1)数据能否正常同步,我们使用Robo 3T,修改20这台的document,如下:
然后,在到从机看下,发现数据能正常同步
2)主机宕机,从机能否自动升级为主机
先查看下主机和从机状态,
此时,我们把主机服务停掉。在主机上再查看状态,出现连接不上
我们到其中的一台从机看下状态,
说明,主从切换没有问题。如果原先的主机在启动,又会怎样呢?
发现原先主机重启之后,变成从机了,这很好理解,先来后到嘛!可是过了半分钟左右,它又变成主机了,这是为什么呢?
这是因为,在rs.conf()配置中, 20这台priority的值比其他台的大。因此,他们又把主导权交还给20服务器了。
二、分片副本集部署
1、准备工作
1.1、分片部署可以很好的起到降压分流的效果,读和写都会根据哈希等算法得到的值去config-server获取数据所落在的服务器。为了能支持分片部署,就需要多台服务器。资源有限,我们选用三台服务器来模拟分片部署。
1.2、服务器规划
1.3、路径规划
1) mongos 路由服务器
mkdir -p /app/mongodb/mongos/logs # 配置路由服务器日志存放路径
2) config 配置服务器
mkdir -p /app/mongodb/config/data # 配置config服务器数据存放路径
mkdir -p /app/mongodb/config/logs # 配置config服务器日志存放路径
3) shard1
mkdir -p /app/mongodb/shard1/data # 配置shard1服务器数据存放路径
mkdir -p /app/mongodb/shard1/logs # 配置shard1服务器日志存放路径
4) shard2
mkdir -p /app/mongodb/shard2/data # 配置shard2服务器数据存放路径
mkdir -p /app/mongodb/shard2/logs # 配置shard2服务器日志存放路径
5) shard3
mkdir -p /app/mongodb/shard3/data # 配置shard3服务器数据存放路径
mkdir -p /app/mongodb/shard3/logs # 配置shard3服务器日志存放路径
6) 统一配置
mkdir -p /app/mongodb/conf/ # 统一配置路径
1.4、效果图
2、config server 集群配置
2.1、配置文件
### 1、systemLog
#日志文件位置
logpath=/app/mongodb/config/logs/config.log
# 以追加方式写入日志
logappend=true
### 2、processManagement
# 进程id
pidfilepath=/app/mongodb/config/config.pid
# 是否以守护进程方式运行
fork=true
### 3、network interfaces
# 绑定ip地址
bind_ip=0.0.0.0
# 默认27017
port=21000
### 4、数据存放
#数据库文件位置
dbpath=/app/mongodb/config/data
### 5、集群
# 副本集名称
replSet=config
# 这是一个集群的配置数据服务
configsvr=true
同时复制到另外两台服务器。
2.2、启动配置服务器, 三台都需要启动,不然下一步执行初始化时会报连接不上的错误, 连接不上可能是服务器没启动, 也可能是其他服务器有防火墙(端口开放)。
2.3、初始化设置
# 登录配置服务器, 任意一台都可以, 21000 是配置服务器的端口
mongo --port 21000
# 使用admin来操作,不用也可以
use admin
# 配置文件
config = {
_id : "config", # 这个config 是配置文件中集群的名称, replSet=config
members : [
{_id : 0, host : "192.168.12.179:21000" },
{_id : 1, host : "192.168.12.180:21000" },
{_id : 2, host : "192.168.12.184:21000" }
]
}
# 初始化
rs.initiate(config)
# 查看状态, 刚开始默认都是 SECONDARY 之后会自动选举出 PRIMARY
rs.status();
3、shard server 分片服务器集群配置
3.1 配置文件
### 1、systemLog
#日志文件位置
logpath=/app/mongodb/shard1/logs/shard1.log
# 以追加方式写入日志
logappend=true
### 2、processManagement
# 进程id
pidfilepath=/app/mongodb/shard1/shard1.pid
# 是否以守护进程方式运行
fork=true
### 3、network interfaces
# 绑定ip地址
bind_ip=0.0.0.0
# 默认27017
port=27001
### 4、数据存放
#数据库文件位置
dbpath=/app/mongodb/shard1/data
### 5、集群
# 副本集名称
replSet=rs_shard1
# 分片节点
shardsvr=true
以shard1为例,shard2和shard3类似,需要修改对应的路径和端口号。
3.2、启动shard1服务器, 三台都需要启动,同config server。
3.3、初始化设置
# 登录shard1服务器
# 这个跟上面是有点不太一样,不能登录 arbiterOnly 对应的服务器,不然无法初始化
mongo --port 27001
# 可以不需要
use admin
#定义副本集配置
config = {
_id : "rs_shard1", # shard1.cfg配置文件中的 replSet=rs_shard1
members : [
{_id : 0, host : "192.168.12.179:27001", priority : 2 },
{_id : 1, host : "192.168.12.180:27001", arbiterOnly :true },
{_id : 2, host : "192.168.12.184:27001", priority : 1 }
]
}
#初始化副本集
rs.initiate(config)
#查看分区状态
rs.status();
出错信息如下:
rs.initiate(config)
{
"operationTime" : Timestamp(0, 0),
"ok" : 0,
"errmsg" : "This node, 192.168.12.179:27003, with _id 0 is not electable under the new configuration version 1 for replica set rs_shard3",
"code" : 93,
"codeName" : "InvalidReplicaSetConfig",
"$clusterTime" : {
"clusterTime" : Timestamp(0, 0),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
原因:登录的是 arbiterOnly 对应的服务器,换一台登录即可。
3.4、设置第二、三个分片副本集
跟设置第一个分片副本集类似,需要注意的是:
a、副本集的名称不能重复;
b、端口直接加1即可,27002 和 27003 ;
c、副本节点和仲裁节点,按服务器顺序依次分配;
4、mongos server 路由服务器集群配置
4.1、 配置文件
### 1、systemLog
# 日志文件位置
logpath=/app/mongodb/mongos/logs/mongos.log
# 以追加方式写入日志
logappend=true
### 2、processManagement
# 进程id
pidfilepath=/app/mongodb/mongos/mongos.pid
# 是否以守护进程方式运行
fork=true
### 3、network interfaces
# 绑定ip地址
bind_ip=0.0.0.0
# 默认
port=20000
### 4、
# 如果有多个mongo config的话就用逗号分隔开, 此处的config 是 config 配置文件中 【副本集的名称 replSet=config】
configdb=config/192.168.12.179:21000,192.168.12.180:21000,192.168.12.184:21000
configdb=config/192.168.12.179:21000,192.168.12.180:21000,192.168.12.184:21000
注意:此处的config 是config.cfg 文件中的副本集的名称 replSet=config
4.2、启动mongos server,同样三台都要启动。
注意: config server 和 shard server 启动必须先于mongos server,不然mongos server会启动不起来。
5、串联路由服务器与分片副本集
5.1、登录mongos
# 登录
mongo --port 20000
# 使用 admin 数据库, 必须
use admin
5.2、串联路由服务器与分片副本集
sh.addShard("rs_shard1/192.168.12.179:27001,192.168.12.180:27001,192.168.12.184:27001")
sh.addShard("rs_shard2/192.168.12.179:27002,192.168.12.180:27002,192.168.12.184:27002")
sh.addShard("rs_shard3/192.168.12.179:27003,192.168.12.180:27003,192.168.12.184:27003")
5.3、查看集群状态
sh.status()
5.4、启动分片
# enableSharding只能针对admin数据库运行,适宜选用admin
use admin
db.runCommand( { enablesharding :"testdb"});
# 设置testdb的 testcoll 表需要分片, 根据id哈希值自动分配到不同分片上
db.runCommand( { shardcollection : "testdb.testcoll",key : {id: "hashed"} } )
6、验证测试
6.1、连到路由服务器
mongo --port 20000
# 然后循环插入数据,也可以直接使用工具
6.2、查看分片的状态
db.testcoll.stats();