docker-compose mongodb 副本集

准备

cd /opt/mongos

把 3 个节点的数据目录创建好

mkdir -p ./mongos/{mongo1,mongo2,mongo3}

mongodb 使用 keyFile 进行认证,副本集群中的每个节点的 mongodb 使用 keyFile 的内容作为认证其他成员的共享密码。mongodb 实例只有拥有正确的 keyFile 才可以加入副本集群,集群中所有成员的 keyFile 内容必须相同。

复制代码
# 进入到 mongos 目录中,生成 keyfile 文件
cd ./mongos
# 其中数字 666 可以随便指定
openssl rand -base64 666 > mongodb.key

mongodb 的集群其实有 3 种角色:主节点、从节点、仲裁节点(可选,可有可无)

  • 主节点(Primary):主要负责数据的写操作,当然也可以读取数据,大部分命令需要在主节点才能运行。
  • 从节点(Secondary):从主节点实时同步数据,只能读取数据,不能进行写操作。
  • 仲裁节点(Arbiter):不保留任何数据的副本,只能用来投票选举使用。

本篇博客的演示中,没有去设置仲裁节点,3 个节点都保留数据副本。

一、docker-compose.yml编辑

在 /opt/mongos 目录下创建 docker-compose.yml 文件,内容如下:

复制代码
version: '3.2'
 
services:
  # 服务名称
  mongodb1:
    # 使用最新的 mongodb 镜像
    image: mongo:latest
    # docker 服务启动时,自动启动 mongo 容器
    restart: always
    # 容器的名称
    container_name: mongo1
    # 宿主机中的目录和文件,映射容器内部的目录和文件
    volumes:
      - ./mongos/mongo1:/data/db
      - ./mongos/mongodb.key:/data/mongodb.key
    ports:
      # 宿主机的端口映射容器内的端口
      - 27017:27017
    environment:
      # 初始化一个 root 角色的用户 jobs 密码是 123456
      - MONGO_INITDB_ROOT_USERNAME=jobs
      - MONGO_INITDB_ROOT_PASSWORD=123456
    # 使用创建的桥接网络,把各个 mongodb 容器连接在一起
    networks:
      - mongoNetwork
    # 启动容器时,在容器内部额外执行的命令
    # 其中 --replSet 参数后面的 mongos 是集群名称,这个很重要
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@
  
  mongodb2:
    image: mongo:latest
    restart: always
    container_name: mongo2
    volumes:
      - ./mongos/mongo2:/data/db
      - ./mongos/mongodb.key:/data/mongodb.key
    ports:
      - 27018:27017
    environment:
      - MONGO_INITDB_ROOT_USERNAME=jobs
      - MONGO_INITDB_ROOT_PASSWORD=123456
    networks:
      - mongoNetwork
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@
 
  mongodb3:
    image: mongo:latest
    restart: always
    container_name: mongo3
    volumes:
      - ./mongos/mongo3:/data/db
      - ./mongos/mongodb.key:/data/mongodb.key
    ports:
      - 27019:27017
    environment:
      - MONGO_INITDB_ROOT_USERNAME=jobs
      - MONGO_INITDB_ROOT_PASSWORD=123456
    networks:
      - mongoNetwork
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@
 
# 创建一个桥接网络,把各个 mongodb 实例连接在一起,该网络适用于单机
# 如果在不同的宿主机上,使用 docker swarm 需要创建 overlay 网络
networks:
  mongoNetwork:
    driver: bridge

最后我们启动 docker-compose ,并使用初始化的 root 角色的用户,登录进行配置集群

复制代码
# 在 docker-compose.yml 文件所在的目录下执行命令
docker-compose up -d
# 查看 3 个 mongodb 容器是否已经启动成功
docker ps
# 随便进入其中一个容器,比如进入 mongo1
docker exec -it mongo1 bash
# 使用初始化的 root 角色的用户 jobs 登录 mongodb 中
mongo -u jobs -p 123456
# 执行以下命令配置将 3 个节点初始化为一个副本集群
rs.initiate({
    _id: "mongos",
    members: [
        { _id : 0, host : "192.168.136.129:27017" },
        { _id : 1, host : "192.168.136.129:27018" },
        { _id : 2, host : "192.168.136.129:27019" }
    ]
});

其中 members 中每个节点的 json 主要的配置内容如下:

  • host:节点的 ip 和端口,例如上面的 192.168.136.129:27018
  • arbiterOnly:是否是仲裁节点,默认是 false
  • hidden:是否是隐藏节点
  • priority:优先级 0 - 1000,优先级越大,获取的投票数可能越多,从节点默认值为 1 ,仲裁节点默认值为 0
  • OK,通过以上步骤,mongodb 的副本集群就搭建好了。

二、Navicat 连接验证

创建 4 个连接,分别连接 mongodb 集群,以及 3 个独立的 mongodb 节点用于测试验证,如下图:

当然新部署的集群下目前没有任何数据库。有关集群连接的创建如下图所示:

连接集群内其中一个单节点的连接创建如下图:

三、使用程序连接验证

这里仍然采用上一篇博客的 demo 连接测试,只需要把 application.yml 连接字符串修改一下即可

复制代码
spring:
  data:
    mongodb:
      # 连接字符串格式
      # mongodb://用户名:密码@Ip地址:端口/数据库名
      # 如果使用的是 root 角色的用户登录,则必须在后面加上 authSource=admin 参数
      # 之前在 admin 库中创建了一个 root 角色的账号 jobs
      # 在实际项目中,强烈建议,针对每个数据库创建一个 readwrite 角色的用户
      #uri: mongodb://jobs:123456@192.168.136.128:27017/mytest?authSource=admin
      uri: mongodb://jobs:123456@192.168.136.129:27017,192.168.136.129:27018,192.168.136.129:27019/mytest?authSource=admin&replicaSet=mongos&slaveOk=true
      # 允许在实体类上,通过 @Indexed 创建单字段索引,通过 @CompoundIndex 创建多字段联合索引
      # 注意:这里只是演示注解的使用,实际项目中一般不推荐使用注解创建索引,
      # 最好通过 mongodb 的命令操作 mongodb 管理索引
      auto-index-creation: true

将 3 个节点的 ip 和 端口,使用英文逗号分隔即可,其中主要配置参数如下:

  • authSource=admin 由于我们创建的是 root 角色的账号,因此必须在 admin 库去验证用户名和密码登录
  • replicaSet 指定要连接的 mongodb 集群的名称,也就是部署时设置的集群名称,这个很重要
  • slaveOk 默认是 false,表示读写都从主节点操作,如果设置为 true 表示读写分离,主节点写,从节点读。

我们运行一下 demo 代码中的添加员工的测试代码,然后就可以在集群连接下和各个节点的连接下看到新创建的 mytest 数据库,以及其下面的 tb_employee 表和数据内容,并且都是一致的。

在集群连接下,或者具体的单节点连接下,运行 rs.status() 命令,点击 members 字段,可以查看节点的角色和状态:

可以发现,当前 192.168.136.129:27019 这个节点是主节点,对应 navicat 中的 mongodb 节点3

然后通过 docker ps 查看容器,停止该主节点的容器,再运行 rs.status() 可以发现主节点变成了 192.168.136.129:27017

执行 demo 代码中的修改测试代码,然后再启动刚才停掉的容器,最后发现重启后的节点变成了从节点

另外恢复的节点,数据也很快同步为 demo 测试代码修改后的结果,如下图所示:

相关推荐
冰封之寂1 天前
Docker 资源管理终极指南:CPU、内存与 IO 的精细化控制
linux·运维·服务器·docker·云计算
952361 天前
Docker - 基础
运维·后端·docker·容器
Code_Ignis1 天前
docker国内可用源(持续维护)
运维·docker·容器
吴声子夜歌1 天前
MongoDB 4.x——并发优化
数据库·mongodb
吴声子夜歌1 天前
MongoDB 4.2——入门指南
数据库·mongodb
吴声子夜歌1 天前
MongoDB 4.x——高可靠
数据库·mongodb
码农学院1 天前
Node.js MongoDB构建户外用品GEO优化内容管理平台
数据库·mongodb·node.js
吴声子夜歌1 天前
MongoDB 4.x——治理经验
数据库·mongodb
水中加点糖1 天前
Java中使用远程PlayWright进行网页接口测试(附Docker部署方式)
java·docker·web测试·devtools·playwright·ai自动化测试
梦梦代码精1 天前
PHP 还是 Java?LikeShop 多版本对比,附6条落地避坑建议
低代码·docker·开源·代码规范