MongoDB数据库服务集群部署安装文档
MongoDB服务安装
1.1 获取MongoDB安装包
当前登录用户角色为root 所在目录为/root 操作系统为 Centos6.1
下载地址:https://www.mongodb.com/download-center/community
根据服务器系统获取安装包,当前安装的机器为centos6.1版本,选择REHL 6.2版本
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.6.12.tgz
1.2 安装MongoDB
1.2.1 准备工作
创建安装目录、数据存放目录、日志目录
mkdir /opt/mongodb # 程序安装目录
mkdir -p /var/mongodb/data # 数据存放目录
mkdir -p /var/mongodb/log # mongodb日志目录
1.2.2 安装MongoDB
# 解压缩文件
tar -zxvf mongodb-linux-x86_64-rhel62-3.6.12.tgz
# 移动文件到/opt/mongodb
mv mongodb-linux-x86_64-rhel62-3.6.12/* /opt/mongodb/
# 删除 空目录
rm mongodb-linux-x86_64-rhel62-3.6.12 -r
1.2.3 单实例MongoDB配置文件
mongdodb的服务启动依赖配置文件的设置或者纯命令行参数来设置,命令行参数的方式测试还好,生成环境上不利于管理,这里创建配置文件用来设置mongodb,默认是不存在配置文件的。
vim /opt/mongodb/mongodb.conf
# 以下为配置文件详细配置
# 数据库文件位置
dbpath=/var/mongodb/data
# 日志文件路径
logpath=/var/mongodb/log/mongodb.log
# pid文件路径
pidfilepath=/opt/mongodb/mongod.pid
# 追加的方式写日志
logappend=true
# 绑定ip 默认绑定127.0.0.1
bind_ip=127.0.0.1
# 绑定端口 默认27017
port=27017
# 以守护进程的方式运行
fork=true
# 不同数据库存放在不同目录
directoryperdb=true # 注意该参数需要服务器使用XFS filesystem
# 上述参数如果服务器使用的非XFS filesystem,启动会出错,将该参数改为false
wq 保存配置文件
详细的配置参数可参考:
https://www.cnblogs.com/cwp-bg/p/9479945.html
https://www.03sec.com/3176.shtml
YAML格式配置文件创建
MongoDB在2.6版本开始支持使用yaml格式的配置文件,官方建议使用yaml格式文档
上述相同参数的yaml格式配置文件如下
vim /opt/mongodb/mongodb.yaml
# ------------以下为yaml格式配置文件内容----------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "127.0.0.1" #绑定ip地址
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data" #数据文件路径
directoryPerDB: false #一个库一个文件,此参数与服务器使用的文件系统有关
注意:以下操作涉及到的配置文件如无特殊说明,均为yaml格式配置
1.2.4 启动服务
# -f 指定配置文件路径 等同 --config
# 以下两个命令二选一 效果完全一致
/opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf
/opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml
启动成功后会提示如下
child process started successfully, parent exiting
使用ps查看是否成功启动
ps aux|grep 'mongod'
1.2.5 指定用户mongodb运行mongodb服务
# 创建用户组mongodb
groupadd mongodb
# 创建用户 mongodb (不允许登录)
useradd mongodb -g mongodb -s /bin/false
# 修改文件所有者
chown -R mongodb:mongodb /opt/mongodb # 安装目录
chown -R mongodb:mongodb /var/mongodb # 数据存储目录
# 使用ps查看是否有mongodb进程
ps aux|grep 'mongod'
如果有进程,使用kill结束进程
kill -9 [pid]
使用mongodb用户启动mongodb服务sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml
1.2.6 添加环境变量
vim /etc/profile
文件最后增加如下配置export PATH=$PATH:/opt/mongodb/bin
加载配置,使环境变量生效source /etc/profile
配置成功后,可直接使用命令 mongod -f /opt/mongodb/mongodb.yaml
来开启mongodb服务
1.2.7 编写自启动脚本
源码安装的mongodb没有启动脚本,需要写一个启动脚本
vim /opt/mongodb/mongodb.sh
#----------------以下为脚本内容-------------------------
#!/bin/bash
#desc mongodb boot shell
MGDB_PATH="/opt/mongodb"
MGDB_CONF="${MGDB_PATH}/mongodb.yaml"
MGDB_USER="mongodb"
MGDB_GROUP="mongodb"
cd ${MGDB_PATH}
MGDB_START(){
if [ ` ps -ef|grep 'mongod -f'|grep -v grep|wc -l` > 0 ];then
echo "MongoDB already start"
exit 1
fi
sudo -u ${MGDB_USER} -g ${MGDB_GROUP} ${MGDB_PATH}/bin/mongod -f ${MGDB_CONF}
if [ $? -eq 0 ];then
echo -n "MongoDB start "
echo -n "["
echo -ne "\033[32m"
echo -n "Successful"
echo -ne "\e[0m"
echo "]"
else
echo "MongoDB start failed"
fi
}
MGDB_STOP(){
sudo -u ${MGDB_USER} -g ${MGDB_GROUP} ${MGDB_PATH}/bin/mongod -f ${MGDB_CONF} --shutdown
if [ $? -eq 0 ];then
echo -n "MongoDB stop "
echo -n "["
echo -ne "\033[32m"
echo -n "Successful"
echo -ne "\e[0m"
echo "]"
else
echo "MongoDB stop failed"
fi
}
MGDB_STATUS(){
ps -ef|grep 'mongod -f'|grep -v grep
if [ $? != 0 ];then
echo "MongoDB is STOP"
fi
}
case "$1" in
start)
MGDB_START
;;
stop)
MGDB_STOP
;;
status)
MGDB_STATUS
;;
restart)
MGDB_STOP
MGDB_START
;;
*)
echo $"Usage: $0 { start | stop | status | restart }"
exit 1
esac
保存脚本后添加到自启动程序
# 添加可执行权限
chmod +x /opt/mongodb/mongodb.sh
# 添加自启动服务
cp /opt/mongodb/mongodb.sh /etc/init.d/mongodb
Centos6.x使用service管理服务
# 启动服务
service mongodb start
# 停止服务
service mongodb stop
# 查看服务状态
service mongodb status
Centos7.x使用service管理服务
# 启动服务
systemctl start mongodb
# 停止服务
systemctl stop mongodb
# 查看服务状态
systemctl status mongodb
1.2.8 对外提供服务
# 修改/opt/mongodb/mongodb.yaml
vim /opt/mongodb/mongodb.yaml
# 将bindIp修改为0.0.0.0
bindIp=0.0.0.0
# 保存
# 重启 mongodb服务
service mongodb restart
Centos6.x
查看防火墙状态service iptables status
如果防火墙开启状态,则关闭防火墙service iptables stop
Centos7.xsystemctl stop firewalld.service
1.2.9 使用shell操作mongodb
直接执行如下命令 可连接到本地mongodb服务mongo
使用参数可指定服务器mongo --host x.x.x.x --post 27017
集群部署配置
2.1 准备工作
现有机器M5-M9,ip地址如下
机器名 | ip地址 | 说明 | |
---|---|---|---|
M5 | 10.1.1.245 | ||
M6 | 10.1.1.246 | ||
M7 | 10.1.1.247 | ||
M8 | 10.1.1.248 | ||
M9 | 10.1.1.249 |
所有机器按如上步骤,部署成单机版本mongodb
快捷方式
注意本快捷方式仅适用于此次的环境,非通用。可略过此部分内容。
因为MongoDB的安装方式仅仅是解压缩,相当于windows上的绿色程序,不存在编译过程,服务器系统一致的情况下,可将安装好的mongdb打包,发送到需要部署的机器上。
cd /opt && zip mongodb.zip mongodb -r
# 使用scp远程复制到需要部署的服务器
scp mongodb.zip root@x.x.x.x:/opt
# 依次执行以下命令可完成安装部署
unzip /opt/mongodb.zip -d /opt
mkdir -p /var/mongodb/data
mkdir -p /var/mongodb/log
useradd mongodb
chown -R mongodb:mongodb /var/mongodb
chown -R mongodb:mongodb /opt/mongodb
cp /opt/mongodb/mongodb.sh /etc/init.d/mongodb
echo 'export PATH=$PATH:/opt/mongodb/bin' >> /etc/profile
source /etc/profile
service mongodb start
2.2 说明
MongoDB共有三种集群搭建方式,分别为
Replica Set(副本集)、
Sharding(分片)
Master-Slaver(主从)【目前已不推荐使用!!!】
三种集群方式的详细说明在下面的部署方案中,实现的方式都是通过更改配置来实现的,所以不同的部署方式有不同的配置文件,集群部署的配置文件命名规则统一为如下格式
mon_xx_yy_0.yaml
mon : 固定格式 代表mongodb
xx : 代表集群方式 枚举[‘ms’,’rs’,’s’] 分别代表三种部署方式首字母小写
yy : 代表所在集群方式中的节点类型
ms集群中 包含[‘master’,’slaver’]两种
rs集群中 包含[‘primary’,’ secondaries’,’ arbiter’]三种
s集群中 包含[‘shard,’config’, ’route’]两种
0 : 启动权重, 集群部署的机器有启动顺序的要求。0为首先需要启动的机器,其他机器权重一次后延,同权重机器启动顺序无要求。
备注:启动失败就随时查看日志文件,失败的原因会在日志中展示。
2.3 Master-Slaver主从复制 集群搭建
2.3.1 Master-Slaver部署说明
最简单的集群搭建,不过准确说也不能算是集群,只能说是主备。
并且官方已经不推荐这种方式,所以在这里只是简单配置,搭建方式也相对简单。
节点说明:
master:主从复制中的主节点,只允许有一个,对外提供读写服务
slaver: 从节点,不提供服务,只同步主节点的数据,主节点故障,可手动切换。
官方文档地址:https://docs.mongodb.com/v3.6/core/master-slave/index.html
优点:搭建简单、可用于备份、故障恢复、读扩展等。
缺点:不支持故障转移,对大量数据的支持较差
备注:可在程序层面实现故障转移,可用于备份,故障恢复,读扩展等。
2.3.2 服务器规划
所有机器都已部署成单实例mongodb服务器,原配置文件为所在位置为
/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。
机器名 | ip地址 | 配置文件 | 说明 |
---|---|---|---|
M5 | 10.1.1.245 | mon_ms_slaver_1.yaml | 备节点 |
M6 | 10.1.1.246 | mon_ms_master_0.yaml | 主节点 |
M7 | 10.1.1.247 | mon_ms_slaver_1.yaml | 备节点 |
M8 | 10.1.1.248 | mon_ms_slaver_1.yaml | 备节点 |
M9 | 10.1.1.249 | mon_ms_slaver_1.yaml | 备节点 |
2.3.3配置文件编写
在M6服务器上编辑master配置文件
vim /opt/mongodb/mon_ms_master_0.yaml
# ---------------以下为master服务器配置--------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "10.1.1.246" #服务器自己的IP地址
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
在M5服务器上编辑slaver 配置文件
vim mon_ms_slaver_1.yaml
# ----------------以下为slaver服务器详细配置--------------------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "10.1.1.245" # 服务器的ip
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
将slaver配置文件复制到M7、M8、M9机器上,或者在其他机器上手动创建配置文件,注意更改IP地址。
2.3.4 服务启动
登入M6机器,启动master节点
注意:这里不能使用启动脚本来启动文件,启动脚本中的配置文件固定为单实例配置,如需使用启动脚本,需要更改启动脚本中的MGDB_CONF变量
# 启动脚本的修改, 可略过
vim /etc/init.d/mongodb
# 原
MGDB_CONF="${MGDB_PATH}/mongodb.yaml"
# 修改后
MGDB_CONF="${MGDB_PATH}/mon_ms_master_0.yaml"
# 其他slaver服务器类似,修改配置文件所在即可
注意:有的时候服务无法启动,只是提示使用without --fork 启动,可通过日志查看原因,或者在确保数据已备份的前提下,将/var/mongodb/data/ 下的内容清空即可命令如下rm /var/mongodb/data/* -rf
启动master
# --master参数 代表当前服务使用master模式运行
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_ms_master_0.yaml --master
依次登录M5、M7、M8、M9机器使用以下命令启动slaver节点
# --slave指定运行模式 --source 指定master的ip:port
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_ms_slaver_1.yaml --slave --source 10.1.1.246:27017
服务成功启动后,查看master日志,有客户端连入的字样received client metadata
2.3.5 数据同步测试
在任意机器上使用mongo连接master, 在主从模式中,只有master节点可读写,slaver节点只能读。
mongo --host 10.1.1.246
# ---以下命令执行环境为mongo的shell客户端
use school; # 选择school库,没有会创建
db.createCollection('student'); # 创建名为student的集合
# 向集合中插入三条数据
db.student.insert({'name':'Xinu1', score:99});
db.student.insert({'name':'Xinu2', score:100});
db.student.insert({'name':'Xinu3', score:80});
exit
# 更换任意slaveer节点,查看数据是否同步
mongo --host 10.1.1.249
# ---以下命令执行环境为mongo的shell客户端
rs.slaveOk(); # 正常slaver节点不允许读取操作,使用此方法,获取当前连接临时读取授权
show dbs; # 查看当前节点中的数据库
use school;
show collections; # 查看当前节点中的集合
db.student.find(); # 查看集合student中的数据
主从模式搭建费成功的话,可以看到如下图的数据。主从复制搭建成功。
2.3.6 故障处理
master-slaver复制模式所有的服务都有master提供,master故障后,需要手动调整任意一个slaver节点为master节点
以M5节点为例,将M5节点变为master节点
# 查找当前mongod服务进程号
ps aux|grep 'mongod'|grep -v grep
# 杀掉该进程
kill -9 [pid]
# 删除 M5节点中数据目录中的 local.*
rm /var/mongodb/data/local.* -rf
# 重命名配置文件
mv /opt/mongodb/mon_ms_slaver_1.yaml /opt/mongodb/mon_ms_master_0.yaml
# 以--master方式运行
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/ mon_ms_master_0.yaml --master
其他从节点停止服务,重新启动 参数--source修改为10.1.1.245:27017
2.4 Replica Set副本集 集群搭建
2.4.1 Replica Set部署说明
官方推荐的搭建方式,同时也是最流行的集群搭建方式。支持故障自动转移,读写分离,有较好的性能和容灾能力。
一个副本集即为服务于同一数据集的多个 MongoDB 实例,其中一个为主节点,其余的都为从节点。主节 点上能够完成读写操作,从节点仅能用于读操作。主节点需要记录所有改变数据库状态的操作,这些记录 保存在 oplog 中,这个文件存储在 local 数据库,各个从节点通过此 oplog 来复制数据并应用于本地,保持 本地的数据与主节点的一致。oplog 具有幂等性,即无论执行几次其结果一致,这个比 mysql 的二进制日 志更好用。
集群中的各节点还会通过传递心跳信息来检测各自的健康状况。当主节点故障时,多个从节点会触发一次 新的选举操作,并选举其中的一个成为新的主节点(通常谁的优先级更高,谁就是新的主节点),心跳信 息默认每 2 秒传递一次。
节点说明:
primary:主节点,只有一个,对外提供读写服务,记录在其上所有操作的 oplog。
secondary: 从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。默认情况下,从节点不支持外部读取,但可以设置;副本集的机制在于主节点出现故障的时候,余下的节点会选举出一个新的主节点,从而保证系统可以正常运行。
arbiter:仲裁节点,副本集部署非必须部署仲裁节点,仲裁节点是为了更好的选举主节点。不复制数据,仅参与投票。由于它没有访问的压力,比较空闲,因此不容易出故障。由于副本集出现故障的时候,存活的节点必须大于副本集节点总数的一半,
否则无法选举主节点,或者主节点会自动降级为从节点,整个副本集变为只读。因此,增加一个不容易出故障的仲裁节点,可以增加有效选票,降低整个副本集不可用的风险。仲裁节点可多于一个。也就是说只参与投票,不接收复制的数据,也不能成为活跃节点。如果副本集的节点总数为奇数,则无需部署仲裁节点,节点总数为偶数,则配置一个仲裁节点拥有选举权。为测试使用仲裁节点,本次部署5个节点,1主3从1仲裁。
官方文档地址:https://docs.mongodb.com/v3.6/tutorial/deploy-replica-set
其它参考文档:https://www.cnblogs.com/kevingrace/p/5685486.html
优点:自动故障转移、自动恢复、读写分离
缺点:部署略有难度提升
备注:比较流行的部署方式,满足大部分业务场景需求
2.4.2 服务器规划
所有机器都已部署成单实例mongodb服务器,原配置文件为所在位置为
/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。
注意:如果机器部署过其它方式的集群,在部署前,请清空所有实例的data目录rm /var/mongodb/data/* -rf
机器名 | ip地址 | 配置文件 | 说明 |
---|---|---|---|
M5 | 10.1.1.245 | mon_rs_arbiter_2.yaml | 仲裁节点 |
M6 | 10.1.1.246 | mon_rs_primary_0.yaml | 主节点 |
M7 | 10.1.1.247 | mon_rs_secondary_1.yaml | 从节点 |
M8 | 10.1.1.248 | mon_rs_secondary_1.yaml | 从节点 |
M9 | 10.1.1.249 | mon_rs_secondary_1.yaml | 从节点 |
2.4.3 配置文件编写
Replica Set副本建官方推荐数据开启auth校验,下面是开启auth校验的准备工作
准备工作(以下操作均在M6节点上)
使用单例模式的配置,开启服务,使用mongo客户端连接,并创建一个用户
# 单实例模式开启mongodb服务
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml
# 使用mongo连接实例
mongo --host 10.1.1.246
# mongodb的auth校验非常完善,本文档不做详细赘述,内容实在太多了
# 参考地址 https://docs.mongodb.com/v3.6/core/authentication/
# 创建root角色组下的用户 用户名为 rsadmin 密码123456
use admin;
db.createUser({user:'rsadmin', pwd:'123456', roles:['root']});
# 该root角色组拥有管理用户组、集群、数据的绝大部分权限,实际生产环境中应谨慎创建
exit
auth校验是针对数据库层面的校验,可以对应为mysql的用户概念,主要是为了数据安全
而集群间的认证也是有必要的,这里开启keyFile。
使用openssl命令创建key
# -base64 使用base64编码 512代表字节长度
openssl rand -base64 512 >> /opt/mongodb/mongo.key
chmod 600 /opt/mongodb/mongo.key # 修改key文件权限
# 将创建的mongo.key复制到其他节点的相同路径下,方便管理
scp /opt/mongodb/mongo.key root@10.1.1.247:/opt/mongodb/
# 其他机器ip依次替换即可
# 复制成功后需要改动mongo.key文件的所有者
chown mongodb:mongodb /opt/mongodb/mongo.key
准备工作做完,配置M6 Primary节点配置
vim /opt/mongodb/mon_rs_primary_0.yaml
# -------------以下为配置文件的内容--------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
component:
replication:
rollback:
verbosity: 5
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "10.1.1.246"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
journal:
enabled: true
replication:
replSetName: 'rs0' # 副本集的名字,所有节点都要一致
security:
keyFile: '/opt/mongodb/mongo.key' # key文件路径 上一步生成的
clusterAuthMode: 'keyFile' # 校验方式为keyFile
配置M7、M8、M9 Secondary节点配置(与Primary节点无区别,除了IP)
vim /opt/mongodb/mon_rs_secondary_1.yaml
# -------------以下为配置文件的内容--------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
component:
replication:
rollback:
verbosity: 5
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "10.1.1.247"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
journal:
enabled: true
replication:
replSetName: 'rs0' # 副本集的名字,所有节点都要一致
security:
keyFile: '/opt/mongodb/mongo.key' # key文件路径 上一步生成的
clusterAuthMode: 'keyFile' # 校验方式为keyFile
三台从节点机器配置除IP外完全一致。
Arbiter 仲裁节点 M5节点配置文件
仲裁节点与其他节点配置不同,需要创建一个专用的数据存放目录,该目录不存放其他节点数据,只是存储仲裁节点用到的数据。
# 创建仲裁节点存放数据目录
mkdir /var/mongodb/abr
# 修改所有者
chown -R mongodb:mongodb /var/mongodb
# 编辑 仲裁节点的配置内容
vim /opt/mongodb/mon_rs_secondary_1.yaml
# -------------以下为配置文件的内容--------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/mongod.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongod.pid" #pid文件路径
net:
bindIp: "10.1.1.245"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/abr" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'rs0'
security:
keyFile: '/opt/mongodb/mongo.key'
2.4.4 服务启动
MongoDB服务停止的三种方式
主节点以单实例启动后,需要关闭,关闭的方式用三种,
第一种是查询pid kill结束进程,上文有介绍。这种强制停止的方式可能会导致下次启动不起来,需要删除data目录下的mongod.lock文件。
第二种,使用mongodb自带的停止服务的方式,
在启动服务的命令最后加上 --shutdown 参数就能正常关闭服务。
启动命令为sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml
则停止命令为sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.yaml --shutdown
第三种,使用mongo客户端连接后,停止服务
mongo --host 10.1.1.246
use admin;
db.shutdownServer();
推荐使用第二种方式
启动主节点Primary M6节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml
依次启动M7、M8、M9 节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_secondary_1.yaml
启动仲裁节点M5sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_arbiter_2.yaml
都启动成功后,现有的5个节点其实谁都可以成为Primary节点,还需要在主节点上配置
任意节点使用mongo连接主节点服务
mongo --host 10.1.1.246
# 因为开启了auth校验,现在各种命令执行都会提示未校验,需要登录下
use admin;
db.auth('rsadmin', '123456');
# 校验成功会提示1,可以执行各种命令了
# 副本集设置初始化
rs.initiate()
# 添加三个从节点
rs.add('10.1.1.247:27017');
rs.add('10.1.1.248:27017');
rs.add('10.1.1.249:27017');
# 添加仲裁节点
rs.addArb('10.1.1.245:27017');
# 如果添加失败 反馈的errMsg都会有提示失败的原因
# 添加成功后查看状态
rs.status();
# 以下为创建成功的状态显示
{
"set" : "rs0",
"date" : ISODate("2019-05-09T03:08:44.242Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "10.1.1.246:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1791,
"optime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-09T03:08:41Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1557370530, 1),
"electionDate" : ISODate("2019-05-09T02:55:30Z"),
"configVersion" : 5,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "10.1.1.247:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 752,
"optime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-09T03:08:41Z"),
"optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:08:43.694Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.804Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.1.1.246:27017",
"syncSourceHost" : "10.1.1.246:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 5
},
{
"_id" : 2,
"name" : "10.1.1.248:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 270,
"optime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-09T03:08:41Z"),
"optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:08:43.909Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.373Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.1.1.249:27017",
"syncSourceHost" : "10.1.1.249:27017",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 5
},
{
"_id" : 3,
"name" : "10.1.1.249:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 513,
"optime" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1557371321, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2019-05-09T03:08:41Z"),
"optimeDurableDate" : ISODate("2019-05-09T03:08:41Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:08:43.697Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.809Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.1.1.246:27017",
"syncSourceHost" : "10.1.1.246:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 5
},
{
"_id" : 4,
"name" : "10.1.1.245:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 492,
"lastHeartbeat" : ISODate("2019-05-09T03:08:43.683Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:08:42.303Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 5
}
],
"ok" : 1,
"operationTime" : Timestamp(1557371321, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1557371321, 1),
"signature" : {
"hash" : BinData(0,"iEDe4wcimYrLW/cIa0ODX3dHFJY="),
"keyId" : NumberLong("6688855494104186883")
}
}
}
# 查看当前副本集的配置
rs.conf();
# 以下为副本集配置内容
{
"_id" : "rs0",
"version" : 5,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "10.1.1.246:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "10.1.1.247:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "10.1.1.248:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 3,
"host" : "10.1.1.249:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 4,
"host" : "10.1.1.245:27017",
"arbiterOnly" : true,
"buildIndexes" : true,
"hidden" : false,
"priority" : 0,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5cd396a0b36b6340a8634b62")
}
}
重点关注三个参数
hidden: 该参数对Secondary节点起作用,是否显示该节点,如果该节点为true,则该节点只参与数据的备份,有选举权,不能成为主节点,不参与读数据。可以作为数据的备份节点。
priority:改参数代表当前节点的权重,越大权重越高,权重的左右在于决定选举权的顺序,权重越大,则在选举中,优先变成Primary节点,可以看到仲裁节点中该参数为0,没有成为主节点的权利。其他节点该参数为1。
votes:决定该节点是否有选举权,可以理解为当前节点是否有选举Primary节点的资格。
2.4.5 数据同步测试
写服务只有Primaryj节点提供,连接主节点
已连接的略过此步骤
mongo --host 10.1.1.246
use admin;
db.auth('rsadmin', '123456');
# 创建school 库
use school;
db.createCollection('student');
db.student.insert({name:'张三'});
db.student.insert({name:'李四'});
使用其他节点连接其他任意Secondary节点进行测试,这里也需要认证,认证同Primary节点完全一致
mongo --host 10.1.1.247
use admin;
db.auth("rsadmin", "123456");
# 从节点默认不提供读写服务,获取临时授权
rs.slaveOk(); # 该授权仅仅能获取读的授权,写必须在主节点上
use school;
db.student.find();
# 以下为内容
{ "_id" : ObjectId("5cd3a12895f1c931dac32f9c"), "name" : "张三" }
{ "_id" : ObjectId("5cd3a12d95f1c931dac32f9d"), "name" : "李四" }
数据同步成功
2.4.6 故障自动恢复
1.停止主节点M6 模拟主节点故障宕机sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml --shutdown
连接其他任意节点:
mongo --host 10.1.1.247
# 认证
use admin;
db.auth('rsadmin','123456');
# 查看状态
rs.status();
# -------状态-------------
{
"set" : "rs0",
"date" : ISODate("2019-05-09T03:58:58.347Z"),
"myState" : 2,
"term" : NumberLong(2),
"syncingTo" : "10.1.1.249:27017",
"syncSourceHost" : "10.1.1.249:27017",
"syncSourceId" : 3,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "10.1.1.246:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:58:56.955Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:44:19.236Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "10.1.1.247:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 4577,
"optime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-05-09T03:58:52Z"),
"syncingTo" : "10.1.1.249:27017",
"syncSourceHost" : "10.1.1.249:27017",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 5,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "10.1.1.248:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 3283,
"optime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-05-09T03:58:52Z"),
"optimeDurableDate" : ISODate("2019-05-09T03:58:52Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:58:58.064Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:58:58.063Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.1.1.249:27017",
"syncSourceHost" : "10.1.1.249:27017",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 5
},
{
"_id" : 3,
"name" : "10.1.1.249:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 3527,
"optime" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1557374332, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2019-05-09T03:58:52Z"),
"optimeDurableDate" : ISODate("2019-05-09T03:58:52Z"),
"lastHeartbeat" : ISODate("2019-05-09T03:58:58.035Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:58:57.056Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1557373472, 1),
"electionDate" : ISODate("2019-05-09T03:44:32Z"),
"configVersion" : 5
},
{
"_id" : 4,
"name" : "10.1.1.245:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 3506,
"lastHeartbeat" : ISODate("2019-05-09T03:58:58.037Z"),
"lastHeartbeatRecv" : ISODate("2019-05-09T03:58:56.485Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 5
}
],
"ok" : 1,
"operationTime" : Timestamp(1557374332, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1557374332, 1),
"signature" : {
"hash" : BinData(0,"WCV4july6HgCfPIOsSktsZKp3zI="),
"keyId" : NumberLong("6688855494104186883")
}
}
}
可以看到 10.1.1.246节点的状态时不可到达,不健康的,而10.1.1.249则变成了Primary节点。
Secondary节点被选举为Primary节点的优先权通过参数priority来控制,越大优先级越高,通过该参数可指定从节点变为主节点的顺序,写程序的时候就可以通过配置多个ip地址来实现容灾,自动恢复。
节点自动恢复,重新启动M6节点sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/mon_rs_primary_0.yaml
在任意节点上登录mongo执行rs.status(); 可以看到M6机器自动变为了Secondary节点。
2.5 Sharding 分片集群搭建
2.5.1 Sharding 分片集群部署说明 Sharding 分片集群部署说明
分片是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建。sharding分片很好的解决了单台服务器磁盘空间、内存、cpu等硬件资源的限制问题,把数据水平拆分出去,降低单节点的访问压力。每个分片都是一个独立的数据库,所有的分片组合起来构成一个逻辑上的完整的数据库。因此,分片机制降低了每个分片的数据操作量及需要存储的数据量,达到多台服务器来应对不断增加的负载和数据的效果。
节点说明:
分片服务器(Shard Server)Mongodb3.6版本及之后 该节点必须是副本集
mongod 实例,用于存储实际的数据块,实际生产环境中一个 shard server 角色可由几台机器组成一个 relica set 承担,防止主机单点故障。这是一个独立普通的mongod进程,保存数据信息。可以是一个副本集也可以是单独的一台服务器。
配置服务器(Config Server)Mongodb3.4版本及之后 该节点必须是副本集
mongod 实例,存储了整个 Cluster Metadata,其中包括 chunk 信息。
这是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息。最先开始建立,启用日志功能。像启动普通的 mongod 一样启动
配置服务器,指定configsvr 选项。不需要太多的空间和资源,配置服务器的 1KB 空间相当于真实数据的 200MB。保存的只是数据的分布表。
路由服务器(Route Server)
mongos实例,前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用
起到一个路由的功能,供程序连接。本身不保存数据,在启动时从配置服务器加载集群信息,开启 mongos 进程需要知道配置服务器的地址,指定configdb选项。
官方文档地址:https://docs.mongodb.com/v3.6/tutorial/deploy-sharded-cluster-hashed-sharding/
其它参考文档:https://blog.51cto.com/bigboss/2160311
优点:超大数据量支持,可横向扩展,容灾性能极强,数据分片存储有效提升磁盘读写瓶颈
缺点:部署难度较大、成本较高。满足的生产环境的部署方式至少需要8台服务器 。
备注:大规模应用一般会采用这种架构去构建
2.5.2 服务器规划
所有机器都已部署成单实例mongodb服务器,原配置文件为所在位置为
/opt/mongodb/mongodb.yaml,不同部署方式有不同的配置文件。
注意:如果机器部署过其它方式的集群,在部署前,请清空所有实例的data目录,如果使用新的data路径则不需要清除
rm /var/mongodb/data/* -rf
由于shard和config节点必须是副本集,而机器数量不够,这里通过配置不同端口来实现多台服务器的模拟。
这里的配置文件命名格式不再遵循上述的命名格式。
机器名 | ip地址-端口 | 配置文件 | 说明 |
---|---|---|---|
M5-27017 | 10.1.1.245:27017 | shard1-rs-1.yaml | shard1 |
M5-27018 | 10.1.1.245:27018 | shard1-rs-2.yaml | shard1 |
M5-27019 | 10.1.1.245:27019 | shard1-rs-3.yaml | shard1 |
M6-27017 | 10.1.1.246:27017 | shard2-rs-1.yaml | shard2 |
M6-27018 | 10.1.1.246:27018 | shard2-rs-2.yaml | shard2 |
M6-27019 | 10.1.1.246:27019 | shard2-rs-3.yaml | shard2 |
M7 | 10.1.1.247 | config-rs-1.yaml | config |
M8 | 10.1.1.248 | config-rs-2.yaml | config |
M9 | 10.1.1.249 | mongos.yaml | mongos |
服务器规划说明:
M5节点搭建为3节点(1主2从0仲裁)的rs0副本集 作为shard1节点
M6节点搭建为3节点(1主2从0仲裁)的rs1副本集 作为 shard2节点
M7,M8搭建成2节点(1主1从0仲裁)的config副本集 作为config节点
M9 作为mongos节点 起到路由的作用。
真正的生产环境中,所用节点都为独立服务器,且mongos应部署多个,每个应用程序服务器都应该部署一个mongos
2.5.3 准备工作
创建通用校验key
# 创建通用公钥文件
openssl rand -base64 512 > /opt/mongodb/mon.key
# 修改文件所有者
chown -R mongodb:mongodb /opt/mongodb/mon.key
# 修改文件权限
chmod -R 600 /opt/mongodb/mon.key
# 依次复制到其他节点
#注意:复制过去以后,该文件的所有者为root 需要重新改成mongodb
scp /opt/mongodb/mon.key 10.1.1.246:/opt/mongodb/
scp /opt/mongodb/mon.key 10.1.1.247:/opt/mongodb/
scp /opt/mongodb/mon.key 10.1.1.248:/opt/mongodb/
scp /opt/mongodb/mon.key 10.1.1.249:/opt/mongodb/
2.5.4 config副本集部署
官方推荐config的副本集生产环境上不低于3个节点,这里只搭建了一个2节点的config server
M7节点
# M7 节点
# 创建数据存放目录、日志存放目录、修改所有者
mkdir -p /var/mongodb/configdata
chown -R mongodb:mongodb /var/mongodb
# 配置 config-rs-1.yaml 文件
vim /opt/mongodb/config-rs-1.yaml
# 内容如下
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/config.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/config.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/configdata" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'config'
security:
keyFile: '/opt/mongodb/mon.key'
sharding:
clusterRole: 'configsvr'
M8节点
# M8 节点
# 创建数据存放目录、日志存放目录、修改所有者
mkdir -p /var/mongodb/configdata
chown -R mongodb:mongodb /var/mongodb
# 配置 config-rs-2.yaml 文件
vim /opt/mongodb/config-rs-2.yaml
# 内容如下
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/config.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/config.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/configdata" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'config'
security:
keyFile: '/opt/mongodb/mon.key'
sharding:
clusterRole: 'configsvr'
启动M7、M8上的服务
# 分别在M7、M8节点启动服务
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/config-rs-1.yaml
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/config-rs-2.yaml
配置config副本集
# 连接M7 或者M8
mongo
# 初始化config副本集
rs.initiate({
_id: "config",
configsvr: true,
version: 1,
protocolVersion: 1,
writeConcernMajorityJournalDefault: true,
members: [
{
_id: 0,
host: "10.1.1.247:27017",
arbiterOnly: false,
buildIndexes: true,
hidden: false,
priority: 66,
tags: {},
slaveDelay: 0,
votes: 1
},
{
_id: 1,
host: "10.1.1.248:27017",
arbiterOnly: false,
buildIndexes: true,
hidden: false,
priority: 55,
tags: {},
slaveDelay: 0,
votes: 1
}
],
settings: {
chainingAllowed : true,
}
});
# 会提示ok:1的字样 通过rs.status() 查看实际运行情况
2.5.5 shard1副本集部署
# shard1 副本集配置
# 创建数据存放目录、日志存放目录、修改所有者
mkdir -p /var/mongodb/data27017
mkdir -p /var/mongodb/data27018
mkdir -p /var/mongodb/data27019
chown -R mongodb:mongodb /var/mongodb
# 配置 shard1-rs-1.yaml 文件
vim /opt/mongodb/shard1-rs-1.yaml
# 内容如下
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/shard1-rs1.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/shard1-rs1.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27017 #实例监听端口
storage:
dbPath: "/var/mongodb/data27017" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'shard1'
security:
keyFile: '/opt/mongodb/mon.key'
sharding:
clusterRole: 'shardsvr'
# 配置 shard1-rs-2.yaml 文件
vim /opt/mongodb/shard1-rs-2.yaml
# 内容如下
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/shard1-rs2.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/shard1-rs2.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27018 #实例监听端口
storage:
dbPath: "/var/mongodb/data27018" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'shard1'
security:
keyFile: '/opt/mongodb/mon.key'
sharding:
clusterRole: 'shardsvr'
# 配置 shard1-rs-3.yaml 文件
vim /opt/mongodb/shard1-rs-3.yaml
# 内容如下
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/shard1-rs3.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/shard1-rs3.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27019 #实例监听端口
storage:
dbPath: "/var/mongodb/data27019" #数据文件路径
directoryPerDB: false #一个库一个文件此参数与系统文件有关
replication:
replSetName: 'shard1'
security:
keyFile: '/opt/mongodb/mon.key'
sharding:
clusterRole: 'shardsvr'
# 启动三个服务
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-1.yaml
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-2.yaml
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongod -f /opt/mongodb/shard1-rs-3.yaml
# 连接27017
mongo
# 初始化shard1副本集
rs.initiate({
_id: "shard1",
version: 1,
protocolVersion: 1,
writeConcernMajorityJournalDefault: true,
members: [
{
_id: 0,
host: "10.1.1.245:27017",
arbiterOnly: false,
buildIndexes: true,
hidden: false,
priority: 66,
tags: {
},
slaveDelay: 0,
votes: 1
},
{
_id: 1,
host: "10.1.1.245:27018",
arbiterOnly: false,
buildIndexes: true,
hidden: false,
priority: 55,
tags: {
},
slaveDelay: 0,
votes: 1
},
{
_id: 2,
host: "10.1.1.245:27019",
arbiterOnly: false,
buildIndexes: true,
hidden: false,
priority: 33,
tags: {
},
slaveDelay: 0,
votes: 1
}
],
settings: {
chainingAllowed : true,
}
});
# 提示 { "ok" : 1 } 则设置成功,通过rs.status() 查看实际运行情况
备注:
- 当前运行的副本集是没有读写执行权限的,分片搭建成功后最后在创建一个用户来操作
- 绑定0.0.0.0以后,通过127.0.0.1的地址登入的用户操作权限略大于通过10.1.1.245的用户,可以执行副本集初始化操作
- 副本集的设置有两种方式,一种是2.4章节中所使用的通过rs.add方法的方式添加从节点,哪个节点发起添加从节点的动作,哪个节点就自动变为主节点,该方式要求用户要有较高的权限,而未添加用户之前,通过127.0.0.1登入的用户也没有add的权限,为了减少操作,这里采用初始化时即配置节点的方式。该配置方式通过priority参数的大小指定端口27017的服务为Primary节点。
2.5.6 shard2副本集部署
将2.5.4中的所有内容中的shard1关键字替换为shard2 地址修改为10.1.1.246即可
与M5节点的搭建方式完全一致,过程略过,如果搭建不出来,You may not be able to make a living by programming.
2.5.7 mongos节点部署
创建mongos数据存放目录 更改目录所有者
mkdir -p /var/mongodb/route
chown -R mongodb:mongodb /var/mongodb
创建mongos节点的配置文件
# ----------以下为配置文件内容------------------
systemLog:
destination: "file" #日志使用文件
path: "/var/mongodb/log/route.log" #日志文件路径
logAppend: true #允许日志追加记录
processManagement:
fork: true #后台守护进程启动
pidFilePath: "/opt/mongodb/mongos.pid" #pid文件路径
net:
bindIp: "0.0.0.0"
port: 27017 #实例监听端口
sharding:
configDB: "config/10.1.1.247:27017,10.1.1.248:27017"
security:
keyFile: '/opt/mongodb/mon.key'
2.5.8 服务启动
shard1、shard2、config三个副本集已启动,这里就是把三个副本集联系到一起。
开启mongos服务
注意:这里是作为路由节点 启动的命令是mongos不是mongod
sudo -u mongodb -g mongodb /opt/mongodb/bin/mongos -f /opt/mongodb/mongos.yaml
# 登录shell
mongo
# 创建高权限用户 root 123456
use admin;
db.createUser({user: "root",pwd: "123456",roles: ['__system']});
exit # 创建成功后退出
# 重新连接
mongo
use admin;
db.auth("root", '123456');
# 添加分片服务器
sh.addShard("shard1/10.1.1.245:27017,10.1.1.245:27018,10.1.1.245:27019");
sh.addShard("shard2/10.1.1.246:27017,10.1.1.246:27018,10.1.1.246:27019");
# 会提示 "shardAdded" : "shard2","ok" : 1类似字样 成功
sh.status(); # 查看当前集群状态
# 为了测试分片效果,修改分片大小
# 修改分片大小为1M 默认为64M
use config;
db.settings.save({_id:"chunksize",value:1});
use school;
db.createCollection('student');
# 对库和student集合使用分片,片键为age 方式为 1
sh.enableSharding('school');
sh.shardCollection("school.student",{'age':1});
# 插入2w条数据
for (i = 1; i <= 20000; i++) db.student.insert({age:(i%100), name:"学生"+i, address:i+"辽宁", country:"中国", course:"cousre"+"(i%12)"});
# 查看分片结果
sh.status();
如上图所示,根据片键age升序分片成功
片键选择:
官网文档:https://docs.mongodb.com/v3.6/core/sharding-shard-key/
https://docs.mongodb.com/v3.6/sharding/#sharding-strategy
其他文档: http://mongoing.com/understand-mongodb-shardkey
http://www.mongoing.com/blog/post/on-selecting-a-shard-key-for-mongodb
片键的分片方式有四种:
1:升序,-1降序,hashed:哈希分布, 还有一种远程分片策略,这里不做详细赘述。
原创,转载请注明来源。