mongodb副本集部署配置文件详解

这个文章是为了解释docker-compose.yml文件,想要查看mongodb副本集部署详细信息,请浏览这篇文章: docker副本集部署mongodb


以下提供 docker-compose.yml 文件的完整注释版本(适用于 MongoDB 副本集初始化的自动配置场景):

version: '3.8'  # 使用 Docker Compose 文件版本 3.8,支持最新功能和特性

services:
  mongo:
    # 使用的 MongoDB 镜像,可从阿里云拉取以加快国内下载速度
    # image: mongo:5.0.18  # 也可以使用官方镜像(默认 Docker Hub)
    image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mongo:5.0.18  # 阿里云加速镜像
    # image: mongo:4.4.29  # 若当前 CPU 不支持 AVX 指令集,可使用旧版本(如在老服务器上运行)

    container_name: mongodb  # 自定义容器名称为 mongodb

    restart: always  # 当容器退出时总是尝试重启,保证服务可用性

    ports:
      - 27018:27017  # 将宿主机 27018 端口映射到容器 27017 端口(MongoDB 默认端口)

    # MongoDB 启动命令,启用副本集并指定密钥文件(用于节点认证)
    command: mongod --keyFile /data/mongodb.key --replSet rs0

    environment:
      - MONGO_INITDB_ROOT_USERNAME=root     # 初始化 root 用户名
      - MONGO_INITDB_ROOT_PASSWORD=123456   # 初始化 root 密码

    volumes:
      - ./mongo_data:/data/db  # 数据卷,将本地目录挂载到容器内部用于数据持久化

    entrypoint:
      - bash
      - -c
      - |  # 使用多行 shell 命令来执行初始化逻辑

        # 1️⃣ 生成副本集密钥文件(用于多个 MongoDB 节点之间的认证)
        openssl rand -base64 128 > /data/mongodb.key
        chmod 400 /data/mongodb.key  # 设置密钥权限为只读,符合 MongoDB 要求
        chown 999:999 /data/mongodb.key  # 更改文件所有者为 MongoDB 默认 UID(999)

        # 2️⃣ 写入副本集初始化 JavaScript 脚本(用于后续 mongo 命令执行)
        echo 'const isInited = rs.status().ok === 1
        if(!isInited){
          rs.initiate({
              _id: "rs0",
              members: [
                  { _id: 0, host: "mongo:27017" }
              ]
          })
        }' > /data/initReplicaSet.js

        # 3️⃣ 后台执行 MongoDB 官方入口脚本(启动 mongod)
        exec docker-entrypoint.sh "$$@" &

        # 4️⃣ 循环等待 MongoDB 服务完全启动可连接
        until mongo -u root -p 123456 --authenticationDatabase admin --eval "print('waited for connection')"; do
          echo "Waiting for MongoDB to start..."
          sleep 2
        done

        # 5️⃣ 使用 root 用户执行副本集初始化脚本
        mongo -u root -p 123456 --authenticationDatabase admin /data/initReplicaSet.js

        # 6️⃣ 等待上面后台启动的 MongoDB 进程(防止容器提前退出)
        wait $$!

✅ 总结这个配置完成的事情:

步骤功能
1️⃣生成副本集认证所需的密钥文件
2️⃣自动生成副本集初始化脚本
3️⃣启动 MongoDB 服务(支持副本集)
4️⃣检查 MongoDB 是否启动成功
5️⃣执行副本集初始化(rs.initiate)
6️⃣等待 MongoDB 服务进程,确保容器不提前结束

下面是提供的 MongoDB 副本集初始化 JavaScript 脚本的详细解释


✅ JavaScript脚本(含详细注释)

// 检查当前 Mongo 实例是否已经初始化了副本集(返回的 rs.status().ok === 1 表示已初始化)
const isInited = rs.status().ok === 1

// 如果还未初始化副本集,则进行初始化
if (!isInited) {
  rs.initiate({
    _id: "rs0", // 副本集名称(必须与 --replSet 参数一致)
    members: [
      {
        _id: 0,             // 成员 ID(必须唯一)
        host: "mongo:27017" // 成员主机名和端口,这里是服务名“mongo”,与 docker-compose 的服务名一致
      }
    ]
  })
}

🔍 小结重点知识:

  • rs.status():查看副本集状态,若尚未初始化会报错。
  • rs.initiate({...}):执行初始化命令,设定副本集 ID 和成员。
  • mongo:27017:此 host 需要与 docker-compose.yml 中的服务名保持一致(即 mongo)。
  • keyFile:确保节点间的认证安全(用于构建更复杂的副本集时必不可少)。

✅ 什么是 MongoDB 副本集(Replica Set)?

副本集(Replica Set) 是 MongoDB 提供的一种 高可用机制,它通过 多个节点的数据同步,来保证数据库的容灾能力和数据一致性。

副本集至少包含:

  • 一个主节点(Primary):可读可写。
  • 一个或多个从节点(Secondary):只读,从主节点同步数据。
  • (可选)一个仲裁节点(Arbiter):用于投票选主,但不存数据。

🔄 它的作用包括:

特性说明
数据高可用主挂了,从会自动升级为新主。应用无需干预即可继续访问
自动故障转移系统自动检测宕机并重新选主
数据冗余所有节点自动同步数据,避免单点丢失
支持读写分离某些从节点可设为只读分流

✅ 为什么这里要配置副本集?

在你的 docker-compose.yml 中,你启动了一个 MongoDB 实例并启用了副本集:

command: mongod --keyFile /data/mongodb.key --replSet rs0

这说明你是以 副本集模式启动 MongoDB 的,即使当前只有一个节点(也称为单节点副本集),也是必要的,原因如下:

✅ 原因一:支持事务

MongoDB 的多文档事务功能仅在 副本集或分片集群中启用。即使是单节点,也必须配置副本集来使用事务功能。

✅ 原因二:兼容未来扩展

一旦你未来需要添加多个 Mongo 节点(如主备架构),不需重构,只要加节点就行。

✅ 原因三:有些高级功能必须依赖副本集

如:

  • Change Streams(变更监听)
  • 写操作的确认机制(Write Concern)
  • 复制集级别的状态监控

✅ 为什么要写这段 JavaScript 初始化脚本?

MongoDB 副本集启动后,默认不会自动初始化副本集配置,所以你需要执行:

rs.initiate({
  _id: "rs0",
  members: [{ _id: 0, host: "mongo:27017" }]
})

这段脚本的目的:

脚本功能说明
rs.status()查看副本集是否已初始化
rs.initiate(...)初始化副本集,指定 ID 和节点信息
host: "mongo:27017"这个 mongo 对应 docker-compose 中的服务名,用于容器内访问
_id: 0成员唯一编号
_id: "rs0"副本集的唯一名称,需与启动参数 --replSet rs0 保持一致

host: "mongo:27017"这里端口对应容器内端口, 详情请参考这篇文章: mongodb副本集部署脚本解释

⛔ 不写这段脚本会怎样?

如果你不执行 rs.initiate()

  • MongoDB 虽然以副本集模式启动,但没有初始化,处于“未就绪”状态。
  • 你连接 Mongo 执行写操作时会出错,如“not master and slaveOk=false”。
  • 事务、Change Streams 等高级功能也无法使用。

✅ 总结

项目说明
什么是副本集MongoDB 的高可用机制,支持主从同步与容灾
为什么启用副本集为了使用事务等功能,即使单节点也需要
为什么写初始化脚本启用副本集后还必须执行初始化指令,否则无法写入数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值