Xinu

Mongodb三种集群部署方式详解
MongoDB数据库服务集群部署安装文档MongoDB服务安装1.1 获取MongoDB安装包当前登录用户角色为r...
扫描右侧二维码阅读全文
13
2019/05

Mongodb三种集群部署方式详解

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.x
systemctl stop firewalld.service

1.2.9 使用shell操作mongodb

直接执行如下命令 可连接到本地mongodb服务
mongo
使用参数可指定服务器
mongo --host x.x.x.x --post 27017

集群部署配置

2.1 准备工作

现有机器M5-M9,ip地址如下

机器名ip地址说明
M510.1.1.245
M610.1.1.246
M710.1.1.247
M810.1.1.248
M910.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地址配置文件说明
M510.1.1.245mon_ms_slaver_1.yaml备节点
M610.1.1.246mon_ms_master_0.yaml主节点
M710.1.1.247mon_ms_slaver_1.yaml备节点
M810.1.1.248mon_ms_slaver_1.yaml备节点
M910.1.1.249mon_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地址配置文件说明
M510.1.1.245mon_rs_arbiter_2.yaml仲裁节点
M610.1.1.246mon_rs_primary_0.yaml主节点
M710.1.1.247mon_rs_secondary_1.yaml从节点
M810.1.1.248mon_rs_secondary_1.yaml从节点
M910.1.1.249mon_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
启动仲裁节点M5
sudo -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-2701710.1.1.245:27017shard1-rs-1.yamlshard1
M5-2701810.1.1.245:27018shard1-rs-2.yamlshard1
M5-2701910.1.1.245:27019shard1-rs-3.yamlshard1
M6-2701710.1.1.246:27017shard2-rs-1.yamlshard2
M6-2701810.1.1.246:27018shard2-rs-2.yamlshard2
M6-2701910.1.1.246:27019shard2-rs-3.yamlshard2
M710.1.1.247config-rs-1.yamlconfig
M810.1.1.248config-rs-2.yamlconfig
M910.1.1.249mongos.yamlmongos

服务器规划说明:
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() 查看实际运行情况  

备注:

  1. 当前运行的副本集是没有读写执行权限的,分片搭建成功后最后在创建一个用户来操作
  2. 绑定0.0.0.0以后,通过127.0.0.1的地址登入的用户操作权限略大于通过10.1.1.245的用户,可以执行副本集初始化操作
  3. 副本集的设置有两种方式,一种是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:哈希分布, 还有一种远程分片策略,这里不做详细赘述。
原创,转载请注明来源。

Last modification:May 17th, 2019 at 10:05 am

Leave a Comment