基于docker-compose构建Mongodb副本集的示例详解

 更新时间:2024年01月30日 09:03:01   作者:Moment  
副本集是 MongoDB 高可用性和数据安全性策略的基础,适用于对数据安全性和服务可用性有较高要求的场景,本文给大家介绍了如何基于docker-compose构建Mongodb副本集,文中通过代码示例给大家介绍的非常详细,需要的朋友可以参考下

MongoDB 副本集是一组维护相同数据集的 MongoDB 服务器。它提供了数据的高可用性和数据冗余。在一个副本集中,有一个节点被选举为 主节点(Primary),负责处理客户端的所有写操作。其他的 次节点(Secondary) 复制主节点的数据。

副本集的主要特点和作用包括:

  • 高可用性:在主节点不可用时,副本集能自动选举一个新的主节点,确保服务的连续性。这对于维护业务的正常运行至关重要。

  • 数据冗余:通过在不同服务器上复制数据,副本集提供了数据冗余,增加了数据的安全性。

  • 故障恢复:在发生硬件故障或数据丢失时,可以从次节点恢复数据。

  • 读写分离:虽然所有写操作都在主节点上进行,但读操作可以在次节点上进行,这样可以分散读操作带来的压力,提高读取性能。

  • 灾难恢复:通过在物理位置不同的地方部署次节点,副本集可以提供地理冗余,从而在发生灾难时保护数据不受影响。

副本集是 MongoDB 高可用性和数据安全性策略的基础,适用于对数据安全性和服务可用性有较高要求的场景。

副本集使用场景一

假设有这样的一个场景,当多个用户或操作同时修改多条数据时,MongoDB 如何处理这些操作取决于是否使用了事务以及所使用的隔离级别。

没有使用事务

MongoDB 在没有使用事务的情况下,对于单个文档提供原子性,但不保证多个操作或多个文档更新的原子性或隔离性。这意味着如果你的第二次修改涉及到由第一次修改影响的数据,可能会遇到以下情况:

  • 脏读:可能读取到其他用户正在修改但尚未完成的数据。
  • 不可重复读:在同一事务内多次读取同一数据集时,可能会看到不同的数据(即,第一次读取时看到一个值,第二次读取时看到另一个值)。
  • 幻读:在一次事务中,一个事务读取了几行数据,然后另一个并发事务插入了一些数据。在第一个事务再次读取时,会发现多了一些原本不存在的记录。

使用了事务

对于副本集,MongoDB 支持多文档事务。在 4.2 版本中,这个支持被扩展到了分片集群。在多文档事务中,可以包含对多个文档的多次读写操作,MongoDB 保证了以下几点:

  • 原子性:事务内的所有操作要么全部成功,要么全部失败。
  • 隔离性:默认情况下,MongoDB 提供了快照隔离级别,这意味着事务将看到一致的数据快照,并且在事务提交之前,其他操作无法看到事务内的更改。

如果你的第二次修改是在一个事务中,并且涉及到第一次修改的数据,MongoDB 会确保按照隔离级别处理这些更改。如果两个操作在不同的事务中,第二个事务会看到第一个事务提交的结果,前提是第一个事务已经成功提交。

虽然事务提供了更强的一致性保障,但也可能对性能有所影响。尤其是在高负载或大规模数据操作时,事务可能会导致延迟增加或资源消耗增大。

基于 docker-compose 来搭建 Mongodb 副本集

首先我们在项目的根目录下创建一个名为 docker-compose.yml 的文件,并且编写如下代码:

version: "3"

services:
  mongodb-primary:
    image: mongo:latest
    container_name: mongodb-primary
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: moment
      MONGO_INITDB_ROOT_PASSWORD: moment
    volumes:
      - ./mongo-keyfile:/opt/keyfile/mongo-keyfile
    command: mongod --replSet rs0 --auth --keyFile /opt/keyfile/mongo-keyfile
    networks:
      - my-network

  mongodb-secondary:
    image: mongo:latest
    container_name: mongodb-secondary
    depends_on:
      - mongodb-primary
    environment:
      MONGO_INITDB_ROOT_USERNAME: moment
      MONGO_INITDB_ROOT_PASSWORD: moment
    volumes:
      - ./mongo-keyfile:/opt/keyfile/mongo-keyfile
    command: mongod --replSet rs0 --auth --keyFile /opt/keyfile/mongo-keyfile
    networks:
      - my-network

  mongodb-arbiter:
    image: mongo:latest
    container_name: mongodb-arbiter
    depends_on:
      - mongodb-primary
    environment:
      MONGO_INITDB_ROOT_USERNAME: moment
      MONGO_INITDB_ROOT_PASSWORD: moment
    volumes:
      - ./mongo-keyfile:/opt/keyfile/mongo-keyfile
    command: mongod --replSet rs0 --auth --keyFile /opt/keyfile/mongo-keyfile --oplogSize 128
    networks:
      - my-network

networks:
  my-network:
    driver: bridge

在上面的这些配置中,我们定义了三个服务:mongodb-primary、mongodb-secondary 和 mongodb-arbiter。这三个服务共同构成了一个 MongoDB 副本集。

  • mongodb-primary: 这是副本集的主节点。它负责处理所有的写操作,并将数据更改复制到次节点。

  • mongodb-secondary: 这是副本集的次节点。它从主节点复制数据,并可以在主节点不可用时被选举为新的主节点。

  • mongodb-arbiter: 仲裁者节点不持有数据,它的作用是在主节点故障时参与选举新的主节点。它存在是为了在有偶数个数据持有节点时提供投票机制,确保总是能够选出一个主节点。

除了这些内容之外,还有一些关键配置项:

  • image: 指定使用的 Docker 镜像,这里使用的是最新版的 MongoDB 官方镜像。

  • container_name: 为每个容器指定一个名字,如 mongodb-primary。

  • ports: 将容器内的 27017 端口映射到宿主机的 27017 端口上,使得可以从宿主机访问 MongoDB 服务。

  • environment: 设置环境变量,包括 MONGO_INITDB_ROOT_USERNAME 和 MONGO_INITDB_ROOT_PASSWORD,这些变量将被用来创建一个具有 root 权限的用户。

  • volumes: 将宿主机上的密钥文件 mongo-keyfile 挂载到容器内的/opt/keyfile/mongo-keyfile。这个密钥文件用于副本集成员之间的认证。

  • command: 容器启动时执行的命令。这里启动了 MongoDB 服务,并通过一系列参数配置了副本集、认证和密钥文件。

  • networks: 指定容器连接的网络。这里定义了一个名为 my-network 的自定义网络,确保容器之间能够相互通信。

  • depends_on: 对于次节点和仲裁者节点,这个选项指定了它们启动的依赖关系,确保它们在主节点启动后再启动。

这些配置完成之后,我们继续在 docker-compose.yml 当前文件目录下继续执行一个命令:

openssl rand -base64 756 > mongo-keyfile

在上面的这些命令中,它将生成一个 1024 位左右的 Base64 编码的随机密钥,并将其保存到名为 mongo-keyfile 的文件中。这个文件随后可以被 MongoDB 的副本集配置用作认证密钥。

keyFile 用于内部节点之间的认证。所有副本集成员使用这个共享的密钥进行相互认证,以确保只有被授权的节点可以加入副本集。

最终生成的文件内容如下图所示:

这些命令都执行完成之后,我们就可以执行 docker-compose up -d 命令来创建和启动 Mongodb 了。

当命令执行完成之后,我们可以查看 docker 容器,最终都被创建成功了

接下来我们就要执行下一个命令了,该命令的作用是启动并连接到名为 mongodb-primary 的运行中的 Docker 容器的 bash shell。一旦进入,你将能够直接在容器的命令行界面中执行命令,就像在任何标准的 Unix/Linux 命令行界面中一样:

docker exec -it mongodb-primary bash

命令执行成功之后,你会看到这样的效果:

这个时候我们需要在终端里继续执行以下命令:

mongosh "mongodb://moment:moment@localhost:27017/?authSource=admin"

这段命令的作用是启动 MongoDB Shell 并尝试使用用户名 moment 和密码 moment 在本地机器上的默认端口 27017 连接到 MongoDB 服务,并在 admin 数据库上进行认证

看到这个效果的时候说明我们的数据库已经连接成功了。

这个时候我们还差最后一步,继续在终端中输入以下命令:

rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongodb-primary:27017" },
    { _id: 1, host: "mongodb-secondary:27017" },
    { _id: 2, host: "mongodb-arbiter:27017" },
  ],
});

该命令的作用是创建一个名为 rs0 的副本集,其中包含三个成员:一个主节点、一个次级节点和一个仲裁者节点。

当命令执行完成之后,我们在执行 rs.status() 来检查当前实例状态,如下图所示,这样的结果表示执行成功:

总结

在本篇文章中,我们学习到了如何使用 docker 来创建一个副本集,以及副本集有什么应用场景。

以上就是基于docker-compose构建Mongodb副本集的示例详解的详细内容,更多关于docker构建Mongodb副本集的资料请关注脚本之家其它相关文章!

相关文章

  • Docker 实用技巧总结

    Docker 实用技巧总结

    这篇文章主要介绍了Docker 实用技巧总结的相关资料,需要的朋友可以参考下
    2016-10-10
  • 为docker中的nginx配置https的方法步骤

    为docker中的nginx配置https的方法步骤

    这篇文章主要介绍了为docker中的nginx配置https的方法步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • Docker 进阶之镜像分层方案详解

    Docker 进阶之镜像分层方案详解

    这篇文章主要介绍了Docker 进阶之镜像分层详解,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-07-07
  • docker容器如何配置hosts文件问题

    docker容器如何配置hosts文件问题

    这篇文章主要介绍了docker容器如何配置hosts文件问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 手工制作docker镜像-包含多个服务ssh+nginx

    手工制作docker镜像-包含多个服务ssh+nginx

    这篇文章主要介绍了手工制作docker镜像-包含多个服务ssh+nginx,需要的朋友可以参考下
    2024-07-07
  • Docker容器的调试技巧之docker logs与docker service logs解读

    Docker容器的调试技巧之docker logs与docker service logs

    这篇文章主要介绍了Docker容器的调试技巧之docker logs与docker service logs,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • 新手必看docker安装jenkins详细教程

    新手必看docker安装jenkins详细教程

    今天给大家分享一篇教程关于docker安装jenkins的步骤,在文中给大家提到了jenkins基本工作原理,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-06-06
  • Dockerfile指令与基本结构的讲解

    Dockerfile指令与基本结构的讲解

    今天小编就为大家分享一篇关于Dockerfile指令与基本结构的讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • docker容器状态转换管理命令实例详解

    docker容器状态转换管理命令实例详解

    Docker容器只是一个运行于宿主操作系统host OS上的应用进程,所以你需要一个镜像来运行它,Docker镜像以进程的方式运行时就叫做Docker容器,这篇文章主要给大家介绍了关于docker容器状态转换管理命令的相关资料,需要的朋友可以参考下
    2022-05-05
  • 阿里云安装docker全过程

    阿里云安装docker全过程

    这篇文章主要介绍了阿里云安装docker全过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论