MongoDB搭建复制集集群(Docker版)

发布时间:2024年01月21日

复制集注意事项

关于复制集:

  • 复制集为 MongoDB 提供了数据可靠性,当某个节点挂掉,可以重新选举出主节点;
  • 复制集为 MongoDB 提供了数据安全性,当节点宕机后,备份数据保证数据不丢失;
  • 复制集为 MOngoDB 提供了高性能,可通过配置主从读写分离提高服务性能;

关于硬件:

  • 因为正常的复制集节点都有可能成为主节点,它们的地位是一样的,因此硬件配置上必须一致;
  • 为了保证节点不会同时宕机,各节点使用的硬件必须具有独立性;
  • 此处用的 Docker 在同一个虚拟机上模拟三个节点;

关于软件:

  • 复制集各节点软件版本必须一致,以避免出现不可预知的问题;
  • 增加节点不会增加系统写性能;
  • 此处用的 MongoDB 6.0.5 版本;

环境准备

  • Docker 安装 MongoDB 并配置好环境变量;
  • 确保有 10GB 以上的硬盘空间;
  • 默认已安装 Docker,没安装的话请参考我的 Docker 教程;
  • 宿主机器为 CentOS7;

一主两从架构图:
image.png

安装步骤

(1)准备配置文件
复制集的每个 mongod 进程应该位于不同的服务器。我们现在在一台机器上运行 3 个进程,因此要为它们各自配置:

  • 不同的端口(28017/28018/28019)
  • 不同的数据目录
mkdir -p /data/db{1,2,3}

image.png

  • 不同日志文件路径(例如:/data/db1/logs)
mkdir -p /data/db{1,2,3}/logs

创建配置文件/data/db1/mongod.conf,内容如下:

systemLog:
  destination: file
  path: /data/logs/mongod.log # log path
  logAppend: true
storage:   
  dbPath: /data/db # data directory      
net:
  bindIp: 0.0.0.0
  port: 27017 # port
replication:
  replSetName: rs0 # 复制集名称
# processManagement: # 设置了该项会导致docker exec -it mongodb1 bash 进入容器后马上自动退出
#   fork: true

将该配置文件复制都 db2、db3 对应的目录下,注意其中配置的是容器中的地址,而不是宿主机对应的地址,且必须是 yaml 格式。
image.png

(2)启动 docker
启动第 1 个 mongod:

docker run --name mongodb1 -d --restart=always -v /data/db1:/data/db -v /data/db1/logs:/data/logs -v /data/db1/mongod.conf:/data/conf/mongod.conf -p 28017:27017 mongo:6.0.5 --config /data/conf/mongod.conf

–name:指定容器名称
-d:后台运行
–restart:设置容器的重启策略,always 表示重启宿主机自动运行 docker
-v:将宿主机文件挂载到容器中,注意格式为:“宿主机路径 : 容器路径”
-p:绑定宿主机和容器的端口,注意格式为:“宿主机端口 : 容器端口”
mongo:6.0.5:指定镜像名和版本号
–config:指定启动的配置文件,容器中的路径

启动第 2 个 mongod:

docker run --name mongodb2 -d --restart=always -v /data/db2:/data/db -v /data/db2/logs:/data/logs -v /data/db2/mongod.conf:/data/conf/mongod.conf -p 28018:27017 mongo:6.0.5 --config /data/conf/mongod.conf

启动第 3 个 mongod:

docker run --name mongodb3 -d --restart=always -v /data/db3:/data/db -v /data/db3/logs:/data/logs -v /data/db3/mongod.conf:/data/conf/mongod.conf -p 28019:27017 mongo:6.0.5 --config /data/conf/mongod.conf

查看 docker 进程状态及网络端口:
image.png
注意 docker 启动,宿主机的防火墙 firewalld 必须开启,否则会报如下错误:
image.png
通过客户端工具访问 mongodb:
image.png
进入 docker 容器操作 mongodb:

# 宿主机进入容器
docker exec -it mongodb1 bash
# 进入容器mongodb的命令行模式
mongosh
# 查看mongodb数据库
show dbs

image.png
至此,三个 mongod 节点安装完成。

配置复制集

复制集通过 mongosh 的 rs.initiate() 进行初始化,初始化后各个成员间开始发送心跳消息,并发起 Priamry 选举操作,获得大多数成员投票支持的节点,会成为 Primary,其余节点成为 Secondary。

进入 mongdb1 节点后执行 mongosh 命令后:

# mongosh --port 28017 
# 初始化复制集
> rs.initiate({
    _id: "rs0",
    members: [{
        _id: 0,
        host: "192.168.10.101:28017"
    },{
        _id: 1,
        host: "192.168.10.101:28018"
    },{
        _id: 2,
        host: "192.168.10.101:28019"
    }]
})

提示{ok:1}表示初始化成功:
image.png

验证主从节点读写操作:

  • MongoDB 主节点进行写入
# mongosh --port 28017
rs0 [direct: primary] test> db.user.insertMany([{name:"firechou"},{name:"monkey"}])

image.png

  • 切换到从节点写入,抛出异常 MongoBulkWriteError: not primary
# mongosh --port 28018  
rs0 [direct: secondary] test> db.user.insertMany([{name:"firechou"},{name:"monkey"}])

image.png

  • MongoDB 从节点进行读
# mongosh --port 28018
# 指定从节点可读
rs0:SECONDARY> rs.secondaryOk() # 需要执行该命令,否则会报错
rs0:SECONDARY> db.user.find()

image.png
或者执行如下命令开启从节点读:

db.getMongo().setReadPref("secondary")

image.png

  • 模拟重新选举 Master

停掉 mongodb1 服务:
image.png
查看 mongodb2 服务已被选举成了 Primary 节点:
image.png
启动 mongodb1 后再次执行写入操作,提示非主节点不能写入:
image.png

复制集状态查询

  • 查看复制集整体状态:
rs.status()

可查看各成员当前状态,包括是否健康,是否在全量同步,心跳信息,增量同步信息,选举信息,上一次的心跳时间等。
image.png
说明:

members:数组,一列体现了所有复制集成员的状态,主要如下:
health:成员是否健康,通过心跳进行检测。
state/stateStr:成员的状态,PRIMARY 表示主节点,而 SECONDARY 则表示备节点,如果节点出现故障,则可能出现一些其他的状态,例如 RECOVERY。
uptime:成员的启动时间。
optime/optimeDate:成员同步最后一条 oplog 的时间。
optimeDurable/optimeDurableDate:成员同步最后一条 oplog 持久化的时间。
pingMs:成员与当前节点的 ping 时延。
syncingTo:成员的同步来源。

  • 查看当前节点角色:
db.isMaster()

除了当前节点角色信息,是一个更精简化的信息,也返回整个复制集的成员列表,真正的 Primary 是谁,协议相关的配置信息等,Driver 在首次连接复制集时会发送该命令。

Mongos 复制集常用命令

**命令 **描述
rs.add()为复制集新增节点
rs.addArb()为复制集新增一个 arbiter
rs.conf()返回复制集配置信息
rs.freeze()防止当前节点在一段时间内选举成为主节点
rs.help()返回 replica set 的命令帮助
rs.initiate()初始化一个新的复制集
rs.printReplicationInfo()以主节点的视角返回复制的状态报告
rs.printSecondaryReplicationInfo()以从节点的视角返回复制状态报告
rs.reconfig()通过重新应用复制集配置来为复制集更新配置
rs.remove()从复制集中移除一个节点
rs.secondaryOk()为当前的连接设置从节点可读
db.getMongo().setReadPref(“secondary”)为当前的连接设置从节点可读,推荐使用
rs.status()返回复制集状态信息
rs.stepDown()让当前的 primary 变为从节点并触发
electionrs.syncFrom()设置复制集节点从哪个节点处同步数据,将会覆盖默认选取逻辑
文章来源:https://blog.csdn.net/u010355502/article/details/135733615
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。