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:[email protected]:27017/mytest?authSource=admin
      uri: mongodb://jobs:[email protected]: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 测试代码修改后的结果,如下图所示:

相关推荐
全镇人的希望2 小时前
[特殊字符] 企业级Docker私有仓库实战:3步搭建Harbor安全仓库,镜像管理从此高效无忧
docker·运维开发·私有化
!!!5253 小时前
Spring Boot MongoDB 分页工具类封装 (新手指南)
spring boot·后端·mongodb
穷儒公羊3 小时前
第一部分——Docker篇 第三章 构建自定义镜像
java·运维·后端·学习·docker·云原生·容器
weixin_428498494 小时前
Docker 容器内运行程序的性能开销
docker·容器
forestsea4 小时前
Docker 是什么? Docker 基本观念介绍与容器和虚拟机的比较
docker·云原生
Gold Steps.5 小时前
基于Kubeadm实现K8S集群扩缩容指南
运维·容器·k8s
!!!5256 小时前
MongoDB 新手笔记
数据库·笔记·mongodb
Mr.Java.6 小时前
Spring Boot MongoDB自定义连接池配置
java·spring boot·后端·mongodb
冯浩(grow up)16 小时前
macOS可视化桌面配置docker加速器
macos·docker·容器
Micheal_Dad16 小时前
在macOS的docker中如何安装及运行ROS2
macos·docker