MongoDB 副本集搭建【带身份认证】 【docker compose + 本机部署】【建议收藏起来】

什么是副本集

MongoDB副本集(Replica Set)是一种数据冗余和故障恢复机制,它允许你维护相同数据的一个或多个副本,并提供自动故障转移和数据恢复能力。副本集是一个包含多个MongoDB实例(通常称为成员)的集合,其中一个成员被选举为主节点(Primary),其他成员作为从节点(Secondary)或仲裁节点(Arbiter)。

副本集的角色:

  • 主节点(Primary):负责处理客户端的读写请求,并将数据更改写入其本地数据文件中。同时,主节点还会将这些更改记录在一个名为oplog(操作日志)的特殊日志文件中,并异步地复制给从节点。
  • 从节点(Secondary):从主节点复制数据,并在本地存储一份副本。默认情况下,从节点默认不处理客户端的读请求,但你可以将其配置为可以读取,从而分散读请求并提高性能。在发生故障时,一个从节点可以被选举为主节点。
  • 仲裁节点(Arbiter):只参与故障转移投票,不存储数据。它通常用于确保副本集具有奇数个成员(以实现多数投票),同时减少存储成本。

副本集的工作机制:

  • 数据复制:主节点将oplog中的更改异步复制到从节点。
  • 故障转移:如果主节点不可用,副本集中的其他成员将尝试选举一个新的主节点。这个过程基于心跳检测和投票机制。
  • 读请求路由:客户端可以将读请求发送到主节点或从节点(如果配置为可读)。

副本集至少需要3个成员,可以配置为一主两从
在这里插入图片描述
如果主节点挂掉,两个从节点会重新选举,找到一个从节点,将其提升为主
在这里插入图片描述
在某些情况下(例如存在一个主节点和一个从节点,但由于成本有限无法再添加另一个从节点),您可以选择将一个实例配置为仲裁节点添加到副本集中。仲裁节点参与选举,但不持有数据(即不提供数据冗余):
在这里插入图片描述
在选举时,主节点可能降为从节点,从节点也可能提升为主节点,但仲裁节点永远只能是仲裁节点。

数据同步原理

Primary节点写入数据,Secondary通过读取Primary的oplog得到复制信息,开始复制数据并且将复制信息写入到自己的oplog。如果某个操作失败,则secondary节点停止从当前数据源复制数据。如果某个secondary节点由于某些原因挂掉了,当重新启动后,就会自动从oplog的最后一个操作开始同步,同步完成后,将信息写入自己的oplog,由于复制操作是先复制数据,复制完成后再写入oplog,有可能相同的操作会同步两份,不过MongoDB的oplog的操作是幂等的,也就是说将oplog的同一个操作执行多次,与执行一次的效果是一样的:

当Primary节点完成数据操作后,Secondary会做出一系列的动作保证数据的同步:

  1. 检查自己local库的oplog.rs集合找出最近的时间戳。
  2. 检查Primary节点local库oplog.rs集合,找出大于此时间戳的记录。
  3. 将找到的记录插入到自己的oplog.rs集合中,并执行这些操作。

secondary从primary端获取日志,然后在本地完全顺序的执行oplog所记录的各种操作(oplog不记录查询操作),这个日志就是local数据库中的oplog.rs表,默认在64位机器上这个表是比较大的,占磁盘大小的5%,oplog.rs的大小可以在启动参数中设 定: --oplogSize 1000,单位是M。

注意:在副本集的环境中,要是所有的Secondary都宕机了,只剩下Primary。最后Primary会变成Secondary,不能提供服务。

oplog 讲解

oplog 详解

部署

Docker compose 部署

创建目录,所有主机都创建

mkdir -p /docker/mongo/{data,logs}

编写 docker-compose.yml 文件,文件在 /docker/mongo 文件夹中

services:
  mongo:
    image: mongo:7.0
    container_name: mongo
    restart: always
    volumes:
      - /docker/mongo/data:/data/db
      - /docker/mongo/logs:/var/log/mongodb
      - /docker/mongo/mongodb-keyfile.key:/etc/mongodb-keyfile.key
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: 123456
      MONGO_INITDB_REPLICA_SET_NAME: rs0
      MONGO_INITDB_DATABASE: admin
    command:
      - /bin/sh
      - -c
      - |
        chmod 400 /etc/mongodb-keyfile.key
        chown 999:999 /etc/mongodb-keyfile.key
        mongod --replSet rs0 --bind_ip_all --auth --keyFile /etc/mongodb-keyfile.key
    networks:
      - mongoNet

networks:
  mongoNet:
    driver: bridge

在随机一台主机上生成密钥

openssl rand -base64 756 > /docker/mongo/mongodb-keyfile.key

分发给其他主机

scp /docker/mongo/mongodb-keyfile.key slave@192.168.142.156:/home/slave
scp /docker/mongo/mongodb-keyfile.key slave02@192.168.142.155:/home/slave02
scp /docker/mongo/mongodb-keyfile.key slave03@192.168.142.158:/home/slave03

在其他主机上

mv /home/<用户名>/mongodb-keyfile.key /docker/mongo

修改文件所属

chown root:root /docker/mongo/mongodb-keyfile.key

开始启动容器

docker compose up -d

当然这句话要在 /mongodb 文件夹下使用
查看集群状态

进入容器
如果 docker exec -it mongo mongosh -u root -p 123456 能直接进入,则可以免去下面创建 root 的过程

无认证登录 mongo 创建 root

docker exec -it mongo mongosh
use admin
rs.initiate()
db.createUser({user:"root",pwd:"123456",roles:[{role:"root",db:"admin"}]})
db.auth("root","123456")

添加节点

rs.add({host:"192.168.142.156:27017",priority: 2})  // 添加第一个从节点
rs.add({host:"192.168.142.155:27017",priority: 3})  // 添加第二个从节点
rs.add({host:"192.168.142.158:27017",arbiterOnly: true})  // 添加第三个从节点 [仲裁节点]

查看集群状态

rs.status()

==============================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值