3种集群模式参考链接:http://c.biancheng.net/view/6567.html
MongoDB 有三种集群部署模式
分别为主从复制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式。
- Master-Slaver 是一种主从副本的模式,目前已经不推荐使用。
- Replica Set 模式取代了 Master-Slaver 模式,是一种互为主从的关系。Replica Set 将数据复制多份保存,不同服务器保存同一份数据,在出现故障时自动切换,实现故障转移,在实际生产中非常实用。
- Sharding 模式适合处理大量数据,它将数据分开存储,不同服务器保存不同的数据,所有服务器数据的总和即为整个数据集。
Sharding 模式追求的是高性能,而且是三种集群中最复杂的。在实际生产环境中,通常将 Replica Set 和 Sharding 两种技术结合使用。
在实际生产环境中,副本集和分片是结合起使用的,可满足实际应用场景中高可用性和高可扩展性的需求。
但是对于我来说,目前只需要用到副本集集群做到故障自动切换、实现高可用,以及支持多文档事务操作即可;
搭建实操
整体集群模式实战参考链接:
Linux:http://c.biancheng.net/view/6568.html
docker:https://segmentfault.com/a/1190000039142073
副本集搭建
docker-compose部署参考链接:
https://www.cnblogs.com/ricklz/p/13237419.html
http://monkeywie.cn/2020/03/10/mongodb-replica-set/?utm_source=tuicool&utm_medium=referral
搭建过程
# 创建挂载需要用到的文件夹(可自定义路径)
# 线上最好分不同的机器搭建,我测试暂时搭建在一台机器上
mkdir -p /ecsmount/docker/mongo-replica-cluster/{mongo-replica-1/{data/db,conf},mongo-replica-2/{data/db,conf},mongo-replica-3/{data/db,conf}}
# 生成auth.key, 用于多节点之间的认证
cd /ecsmount/docker/mongo-replica-cluster
openssl rand -base64 756 > ./auth.key
# 权限设置,为必要步骤
# chown mongodb:mongodb ./auth.key
chown systemd-bus-proxy:ssh_keys ./conf/auth.key
chmod 400 ./auth.key
cp ./auth.key ./mongo-replica-1/conf
cp ./auth.key ./mongo-replica-2/conf
cp ./auth.key ./mongo-replica-3/conf
rm -rf ./auth.key
分别写三个 docker-compose.yml
version: '3.6'
services:
mongo-replica-1:
restart: always
# build: .
image: mongo:4.4.8-rc0-focal
container_name: mongo-replica-1 # 容器名,不同副本使用不同名字
ports:
- 27117:27017 # 外部映射端口改为自定义的端口
volumes:
# 数据目录 挂载出来后,即使删除容器,再用该挂载数据与docker-compose.yml文件启动容器,即可恢复到原来的数据以及用户信息
- ./data/db:/data/db
# 自定义数据备份目录,可以定时全量备份数据出来
- ./mybackup:/mybackup
# conf文件夹
- ./conf:/conf
- /etc/localtime:/etc/localtime
environment:
# 配置root用户, 只需要在第一台机器中配置即可(也可以都配置成一样的,如果不一样,效果未知,可以自己测试一下),其他副本集节点会自动同步过去
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=123
- TZ=Asia/Shanghai
# 缓存大小配置为使用 1.5GB , 考虑服务器中还有其他服务需要占用内存,可自定义大小
- wiredTigerCacheSizeGB=1.5
# 执行命令,覆盖默认命令
# --replSet rs 指定副本集名称为rs
# --keyFile /conf/auth.key 各节点使用一个key进行认证
command: mongod --replSet rs --keyFile /conf/auth.key
# 使用springBoot连接测试后,才知道还好提前配置了hosts, 建议在rs.initiate() 初始化集群时直接写host,不要写局网ip,后面测试时遇到坑也会在后面写到
# 容器中的hosts配置,自定义host与服务器局网IP映射
extra_hosts:
- "server-d-1:172.16.218.205"
- "server-d-2:172.16.0.84"
启动完成后执行初始化命令
docker exec -it mongo-replica-1 bash
mongo
use admin
db.auth("root","123") # rs的相关方法需要先登录才能使用
rs.initiate({ _id: "rs", members: [{_id:1,host:"172.16.0.84:27117"},{_id:2,host:"172.16.0.84:27217"},{_id:3,host:"172.16.0.84:27317"}]})
rs.status()
rs.status() 效果:
#移除节点
rs.remove("172.16.0.84:27317");
# mongo副本集的最小推荐配置是三台,如果服务器资源不够,可以将第三台设置为仲裁节点(仲裁节点只参与投票,不同步数据)
rs.addArb("172.16.0.84:27317");
# 或者是在初始化时就直接将第三台设置为仲裁节点,关键参数:arbiterOnly:true
rs.initiate({ _id: "rs", members: [{_id:1,host:"172.16.0.84:27117"},{_id:2,host:"172.16.0.84:27217"},{_id:3,host:"172.16.0.84:27317", arbiterOnly:true}]})
搭建成功后的补充:关于认证文件的权限设置的说明
- 方法一:直接在宿主机设置(推荐)
1、在mongo容器中需要设置权限: <=400 (直接在宿主机中设置好即可)
chmod 400 ./auth.key
2、在mongo容器中需要设置的用户与组: mongodb:mongodb
# 但是我们还没启动容器,只能在宿主机中先设置为:systemd-bus-proxy:ssh_keys
chown systemd-bus-proxy:ssh_keys ./auth.key
# 启动容器后,发现容器内该文件的 用户:用户组 映射为了 mongodb:mongodb
-
方法二:使用 Entrypoint(未测试)
Entrypoint设置在运行容器时,首先执行的命令和参数。
# 在 docker-compose.yml 中可以定义接入点,覆盖 Dockerfile 中的定义 # 注意是覆盖,确认原镜像中被覆盖没问题的话,可以按其他博主的方法写在 docker-compose.yml中: command: mongod --replSet mongos --keyFile /data/mongodb.key restart: always entrypoint: - bash - -c - | chmod 400 /data/mongodb.key chown 999:999 /data/mongodb.key exec docker-entrypoint.sh $$@ # 该配置片段取自:https://www.cnblogs.com/ricklz/p/13237419.html
搭建过程常用命令
# 停止并删除容器,清空容器挂载数据
docker-compose down
rm -rf ./data/db/*
副本无法查询 :not master and slaveOk=false
因为SECONDARY默认是不允许读写的,
https://stackoverflow.com/questions/8990158/mongodb-replicates-and-error-err-not-master-and-slaveok-false-code
设置方法:
# 两种方法都是一样的效果, 每次mongo 会话都要设置一次
db.getMongo().setSecondaryOk()
rs.secondaryOk();
在其他机器部署新增节点
# 当前服务器(server-d-2) 新机器(server-d-1)
# 在新机器上创建目录
mkdir -p /ecsmount/docker/mongo-replica-cluster/mongo-replica-4/{data/db,conf}
# 新机器需要 auth.key 与 docker-compose.yml 两个文件即可
# 在server-d-2机器上复制以上2个文件到新机器中
scp -P 50148 ./docker-compose.yml root@server-d-1:/ecsmount/docker/mongo-replica-cluster/mongo-replica-4/
scp -P 50148 ./conf/auth.key root@server-d-1:/ecsmount/docker/mongo-replica-cluster/mongo-replica-4/conf/
# 在新机器上检查文件auth.key 权限,一定要设置文件权限
chown systemd-bus-proxy:ssh_keys ./conf/auth.key
chmod 400 ./conf/auth.key
# 修改新机器上的docker-compose.yml中的容器名与外部端口(新机器上不冲突,非必要,但建议还是区分开来)
container_name: mongo-replica-4 # 容器名,不同副本使用不同名字
ports:
- 27417:27017 # 第四个节点
# 新机器上启动后,进入主机PRIMARY中执行添加节点的操作
rs.add("172.16.218.205:27417") # 这个是我新机器的ip地址
rs.status()
在服务器中登陆mondo测试
1、在主节点测试写入、修改、删除数据,是否能同步到其他节点查询到;
2、手动停止主节点容器,观察从节点是否有重新选举主节点;
3、在新的主节点中插入、修改、新增数据,然后启动之前的主节点,观察启动后是否同步了最新的数据过来;
# 过程太繁琐,截图:略!
在springBoot中测试
yml连接配置
spring:
application:
name: springboot-mongodb
data:
mongodb:
uri: mongodb://imAdmin:123456@server-d-2:27117,server-d-2:27217/im?replicaSet=rs # 副本集群主机单节点负责读写
# 关于读写分离的配置,其他博主也有分享一些方案,但是鉴于 “副本滞后” 的影响,结合自己业务情况,决定还是使用单机节点负责读与写,副本节点负责数据同步备份。
跑测试类时报错:
修改集群配置,将局网IP使用host替换
参考链接:mongodb集群修改IP地址 https://blog.csdn.net/wangkai_123456/article/details/109512009
docker exec -it mongo-replica-1 bash
cat /etc/hosts # 确认hosts配置中是否有自己配置的host
# 查看当前配置,准备修改
cfg = rs.conf()
# 修改三个节点的host(把局网IP替换成对应的host)
cfg.members[0].host = "server-d-2:27117"
cfg.members[1].host = "server-d-2:27217"
cfg.members[2].host = "server-d-1:27417"
# 确认修改后的配置
cfg
# 保存配置
rs.reconfig(cfg)
修改前截图:
修改后截图 rs.status()