首页 > 数据库 >使用 DcokerCompose 搭建 mongodb 副本集群

使用 DcokerCompose 搭建 mongodb 副本集群

时间:2023-08-20 12:01:19浏览次数:51  
标签:副本 mongodb DcokerCompose data 集群 mongos root 节点

前面我们搭建了 mongodb 单机环境,但是在实际生产环境中,为了高可用,肯定需要搭建 mongodb 集群。mongodb 集群主要分为两种:副本集群和分片集群。其中副本集群搭建容易,是生产环境中使用最多的集群,因此很有必要掌握。

副本集群比较类似于 mysql 的主从复制,一主多从,每个节点的数据都是一致的。主节点可以读写,从节点只能读。相比于 mysql 的优势在于,mongodb 集群在主节点挂掉后,不需要借助任何第三方工具,可以自己实现内部选举迅速切换主节点,非常方便。当原来挂掉的主节点恢复后,会继续作为从节点,并从新的主节点中同步数据,最终实现各个节点的数据一致性。

mongodb 副本集群能够承载的数据量主要取决于单个节点上的磁盘大小。主要应用场景在于数据实时备份,数据读写分离。对于程序代码连接 mongodb 集群来说,原有代码不需要做任何改动,就能够实现读写分离,非常方便。

本篇博客主要介绍如何使用 DockerCompose 快速搭建 mongodb 集群,满足生产环境的需要。


一、副本集群搭建

我使用的虚拟机 ip 地址是:192.168.136.129,操作系统 CentOS7,已经安装好了 docker 和 docker-compose

由于搭建 mongodb 集群,至少需要 3 个节点,因此我们需要提前把 3 个节点的数据目录创建好。

# 创建 3 个目录,分别用来存放 mongodb 集群 3 个节点的数据
mkdir -p /root/mongos/mongo1
mkdir -p /root/mongos/mongo2
mkdir -p /root/mongos/mongo3

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

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

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

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

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

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

version: '3.2'
 
services:
  # 服务名称
  mongodb1:
    # 使用最新的 mongodb 镜像
    image: mongo:latest
    # docker 服务启动时,自动启动 mongo 容器
    restart: always
    # 容器的名称
    container_name: mongo1
    # 宿主机中的目录和文件,映射容器内部的目录和文件
    volumes:
      - /root/mongos/mongo1:/data/db
      - /root/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:
      - /root/mongos/mongo2:/data/db
      - /root/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:
      - /root/mongos/mongo3:/data/db
      - /root/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 root -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 节点用于测试验证,如下图:

image

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

image

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

image


三、使用程序连接验证

这里仍然采用上一篇博客的 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 表和数据内容,并且都是一致的。

image

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

image

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

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

image

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

image

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

image


标签:副本,mongodb,DcokerCompose,data,集群,mongos,root,节点
From: https://www.cnblogs.com/studyjobs/p/17643808.html

相关文章

  • 剖析MongoDB数据库:理解NoSQL设计模式、优化查询性能和数据安全性
    MongoDB是一个流行的NoSQL文档数据库,它使用JSON样式的文档存储数据。本文将对MongoDB进行剖析,包括NoSQL设计模式、优化查询性能和数据安全性。NoSQL设计模式文档数据库MongoDB采用文档数据库的设计模式,即将相关数据保存在单个文档中,而不是将其拆分成多个表。这种设计模式使得数......
  • 构建高性能的后端服务:使用 Node.js、Express 和 MongoDB
    在现代应用开发中,构建高性能的后端服务是关键所在。本文将介绍如何使用Node.js、Express框架和MongoDB数据库来构建一个高性能的后端服务,实现数据存储与检索。为什么选择Node.js、Express和MongoDB?Node.js:Node.js是一个基于ChromeV8引擎的JavaScript运行时,具有非阻塞......
  • C++快速入门 第三十六讲:副本构造器
    我们可以把一个对象赋值给一个类型与之相同的变量,编译器将生成必要的代码把“源”对象各属性的值分别赋值给“目标”对象的对应成员。这种赋值行为称之为逐位复制。(但如果某些成员变量是指针的话,对象成员逐位复制的结果是你将拥有两个一模一样的实例,而这两个副本里的同名指针会指......
  • MongoDB 审计
    1、启用和配置审计的输出格式使用--auditDestination配置项来启用MongoDB审计和指定输出的审计事件。01、审计日志输出到syslog,如:mongod--dbpath/var/lib/mongo--auditDestinationsyslog或者,在MongoDB配置文件设置,如下:auditLog:destination:syslog02、审计日志......
  • MongoDB入门到精通学习路线?深入讲解
    MongoDB入门到精通学习路线?深入讲解学习MongoDB可以按照以下路线进行:1.学习基本概念:掌握MongoDB的基本概念,包括文档,集合,数据库,索引等。了解MongoDB与传统关系数据库的区别。2.安装和配置MongoDB:学习如何安装和配置MongoDB,包括选择适当的版本和安装方法,并配置正确的环境变量。......
  • 搭建mongo副本集
    1.下载镜像dockerpullmongo:6.0.82.在/data/mongodb目录下新建mongodb-1、mongodb-2、mongodb-3三个文件夹3.生成keyfile文件#400权限是要保证安全性,否则mongod启动会报错opensslrand-base64756>mongodb.keychown999:999mongodb.key将生成的mongodb.key......
  • mongodb 查重与去重
    --查询image重复记录db.getCollection('image').aggregate([{$group:{_id:{imageId:'$imageId',time:'$time'},count:{$sum:1}}},{$match:{count:{$gt:1}}}])--删除image重复记录db.getCollection('image......
  • 使用 SpringData 操作 Mongodb
    本篇博客主要介绍SpringBoot如何通过SpringData操作Mongodb。在上篇博客部署的mongodb为了方便,在admin库中创建了一个root角色的账号,使用这个账号具有最高权限,可以访问和操作任何库。在实际项目中强烈建议为每个mongodb数据库创建一个低权限角色的用户,比如具有readw......
  • 机器人编程教程5使用Git和SD卡副本备份代码
    5使用Git和SD卡副本备份代码在本章中,您将学习到以下内容:代码是如何破坏或丢失的策略1-将代码保存在电脑上并上传策略2:使用Git回溯历史策略3-制作SD卡备份5.1代码是如何破坏或丢失的代码和它的近亲--配置,都需要时间和艰苦的努力。代码需要配置才能运行,例如Ra......
  • MongoDB——Centos五步安装并设置服务自启(一)
     简介:官方地址:MongoDB:TheDeveloperDataPlatform|MongoDBMongoDB是一个开源的NoSQL数据库管理系统,它使用文档型数据模型来存储数据,以下是MongoDB的基本信息文档型数据存储:MongoDB使用BSON(BinaryJSON)格式存储数据,它是一种类似于JSON的二进制表示形式。每个文档是一个包含字......