mongo副本集本地部署

介绍

前言:

mongodb 因为高性能、高可用性、支持分片等特性,作为非关系型数据库被大家广泛使用。其高可用性主要是体现在 mongodb 的副本集上面(可以简单理解为一主多从的集群),本篇文章主要从副本集介绍、docker搭建副本集、副本集读写数据这三个方面来带大家认识下 mongodb 副本集。

mongodb 副本集介绍

mongodb 副本集(Replica Set)包括主节点(primary)跟副本节点(Secondaries)。
主节点只能有一个,所有的写操作请求都在主节点上面处理。副本节点可以有多个,通过同步主节点的操作日志(oplog)来备份主节点数据。
在主节点挂掉后,有选举权限的副本节点会自动发起选举,并从中选举出新的主节点。副本节点可以通过配置指定其具体的属性,比如选举、隐藏、延迟同步等,最多可以有50个副本节点,但只能有7个副本节点能参与选举。虽然副本节点不能处理写操作,但可以处理读请求。搭建一个副本集集群最少需要三个节点:一个主节点,两个备份节点,如果三个节点分布合理,基本可以保证线上数据99.9%安全。如果只有一个主节点,一个副本节点,且没有资源拿来当第二个副本节点,那就可以起一个仲裁者节点(arbiter),不存数据,只用来选举用。当主节点挂掉后,那么两个副本节点会进行选举,从中选举出一个新的主节点。
对于副本集成员属性,特别需要说明下这几个:priority、hidden、slaveDelay、tags、votes。

  • priority
    对于副本节点,可以通过该属性来增大或者减小该节点被选举成为主节点的可能性,取值范围为0-1000(如果是arbiters,则取值只有0或者1),数据越大,成为主节点的可能性越大,如果被配置为0,那么他就不能被选举成为主节点,而且也不能主动发起选举。
  • hidden
    隐藏节点会从主节点同步数据,但对客户端不可见,在mongo shell 执行 db.isMaster() 方法也不会展示该节点,隐藏节点必须Priority为0,即不可以被选举成为主节点。但是如果有配置选举权限的话,可以参与选举。
  • slaveDelay
    延迟同步即延迟从主节点同步数据,比如延迟时间配置的1小时,现在时间是 09:52,那么延迟节点中只同步到主节点 08:52 之前的数据。另外需要注意延迟节点必须是隐藏节点,且Priority为0。
  • tags
    支持对副本集成员打标签,在查询数据时会用到,比如找到对应标签的副本节点,然后从该节点读取数据,这点也非常有用,可以根据标签对节点分类,查询数据时不同服务的客户端指定其对应的标签的节点,对某个标签的节点数量进行增加或减少,也不怕会影响到使用其他标签的服务。
  • votes
    节点是否有权限参与选举,最大可以配置7个副本节点参与选举。

副本集的搭建

下载MongoDB镜像

首先,你需要从Docker Hub或其他Docker镜像仓库下载MongoDB的镜像。这里假设你使用的是MongoDB 4.4.0版本。

docker pull mongo:4.4.0

创建数据目录

在宿主机上创建用于存储MongoDB数据的目录。这些目录将被映射到Docker容器的/data/db目录。

mkdir -p /home/docker/mongodb/data1  
mkdir -p /home/docker/mongodb/data2  
# 如果有更多副本集成员,可以继续创建更多目录

启动MongoDB容器实例

启动多个MongoDB容器实例,每个实例都映射到不同的宿主机端口和数据目录。同时,通过–replSet参数指定副本集的名称。

docker run -d --name mongo1 -p 27017:27017 -v /home/docker/mongodb/data1:/data/db mongo:4.4.0 --replSet rs0  
docker run -d --name mongo2 -p 27018:27017 -v /home/docker/mongodb/data2:/data/db mongo:4.4.0 --replSet rs0  
# 如果有更多副本集成员,继续启动更多容器

注意:在上面的命令中,rs0是副本集的名称,你可以根据需要更改它。

初始化副本集

选择其中一个MongoDB容器实例作为主节点(primary),并初始化副本集。通常,你可以通过连接到MongoDB的admin数据库,并使用rs.initiate()命令来初始化副本集。 首先,你需要进入MongoDB容器实例的shell环境。假设你使用mongo1作为主节点:

docker exec -it mongo1 mongo admin

然后,在MongoDB shell中执行以下命令初始化副本集:

rs.initiate({  
   _id: "rs0",  
   members: [  
      { _id: 0, host: "localhost:27017" },  
      { _id: 1, host: "localhost:27018" }  
      // 如果有更多副本集成员,继续添加  
   ]  
})

注意:在上面的命令中,_id是副本集的名称,members数组包含了副本集成员的地址信息。由于MongoDB容器实例运行在Docker中,所以你需要使用容器内部的地址(在这个例子中是localhost)和端口(这里是27017和27018)。但在实际的生产环境中,你可能需要使用容器的服务名称或Docker网络的IP地址。

添加副本集成员

如果在初始化副本集时没有包含所有成员,你可以通过rs.add()命令添加它们。但是,在上面的步骤中,我们已经在rs.initiate()命令中包含了所有成员,所以这一步可能是可选的。

验证副本集状态

使用rs.status()命令来查看副本集的状态,确认所有成员都已正确加入并处于正确的角色(如主节点、从节点等)。

docker-compose部署

配置文件

  • 生成key文件
openssl rand -base64 20 > keyfile
chmod 400 keyfile
  • 配置文件
# mongod.conf
 
# 指定存储数据文件的目录
storage:
  dbPath: /data/db
 
# 指定日志文件的位置和日志等级
systemLog:
  destination: file
  logAppend: true
  path: /var/log/mongodb/mongod.log
 
# 网络配置
# net:
#   bindIp: 0.0.0.0
 
# 设置复制集的名称
replication:
  replSetName: rs0
 
# 安全性和认证配置
#security:
#  authorization: enabled
  • 存储文件和日志文件
D:\SF\DOCKER\mongo\data1
D:\SF\DOCKER\mongo\data2
D:\SF\DOCKER\mongo\data3
D:\SF\DOCKER\mongo\logs1
D:\SF\DOCKER\mongo\logs2
D:\SF\DOCKER\mongo\logs3

容器配置文件

docker-compose.yml 是 Docker Compose 使用的配置文件,用于定义和运行多容器的 Docker 应用程序。在 docker-compose.yml 文件中,你可以定义应用程序的服务(containers)、网络、卷和其他 Docker 特性。

  • version: ‘3’ 指定了 Compose 文件的版本。
  • services 定义了应用程序的服务。在这个例子中,有两个服务:web 和 db。
  • web 服务:
    • 使用当前目录下的 Dockerfile 构建镜像(通过 build: . 指定)。
    • 映射主机上的 5000 端口到容器的 5000 端口(通过 ports 指定)。
    • 依赖于 db 服务(通过 depends_on 指定)。
    • 设置环境变量 DATABASE_URL(通过 environment 指定)。
  • db 服务:
    • 使用官方的 postgres:13 镜像。
    • 设置环境变量 POSTGRES_USER、POSTGRES_PASSWORD 和 - - POSTGRES_DB(通过 environment 指定)。
    • 挂载一个卷 db_data 到容器的 /var/lib/postgresql/data 目录(通过 - volumes 指定)。
  • volumes 定义了卷,其中 db_data 卷被 db 服务使用。

可以使用 Docker Compose 命令(如 docker-compose up)来启动、停止和重启这个多容器的应用程序。

version: '3.7'
 
services:
  mongo-primary:
    image: mongo:latest
    ports:
      - "27017:27017"
    volumes:
      - D:\SF\DOCKER\mongo\config\mongod.conf:/etc/mongod.conf
      - D:\SF\DOCKER\mongo\config\mongodb.key:/etc/mongodb.key
      - D:\SF\DOCKER\mongo\data1:/data/db
      - D:\SF\DOCKER\mongo\logs1:/var/log/mongodb
    environment:
       MONGO_INITDB_ROOT_USERNAME: root
       MONGO_INITDB_ROOT_PASSWORD: 123456
    command: mongod --replSet rs0 --dbpath /data/db  --keyFile /etc/mongodb.key --config /etc/mongod.conf
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /etc/mongodb.key
        chown 999:999 /etc/mongodb.key
        exec docker-entrypoint.sh $$@
        
  mongo-secondary1:
    image: mongo:latest
    ports:
      - "27018:27017"
    volumes:
      - D:\SF\DOCKER\mongo\config\mongod.conf:/etc/mongod.conf
      - D:\SF\DOCKER\mongo\config\mongodb.key:/etc/mongodb.key
      - D:\SF\DOCKER\mongo\data2:/data/db
      - D:\SF\DOCKER\mongo\logs2:/var/log/mongodb
    depends_on:
      - mongo-primary
    environment:
       MONGO_INITDB_ROOT_USERNAME: root
       MONGO_INITDB_ROOT_PASSWORD: 123456
    command: mongod --replSet rs0 --dbpath /data/db  --keyFile /etc/mongodb.key --config /etc/mongod.conf 
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /etc/mongodb.key
        chown 999:999 /etc/mongodb.key
        exec docker-entrypoint.sh $$@
        
  mongo-secondary2:
    image: mongo:latest
    ports:
      - "27019:27017"
    volumes:
      - D:\SF\DOCKER\mongo\config\mongod.conf:/etc/mongod.conf
      - D:\SF\DOCKER\mongo\config\mongodb.key:/etc/mongodb.key
      - D:\SF\DOCKER\mongo\data3:/data/db
      - D:\SF\DOCKER\mongo\logs3:/var/log/mongodb
    depends_on:
      - mongo-primary
    environment:
       MONGO_INITDB_ROOT_USERNAME: root
       MONGO_INITDB_ROOT_PASSWORD: 123456
    command: mongod --replSet rs0 --dbpath /data/db  --keyFile /etc/mongodb.key --config /etc/mongod.conf  
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /etc/mongodb.key
        chown 999:999 /etc/mongodb.key
        exec docker-entrypoint.sh $$@

容器启动

# 进入docker-compose.yml 文件所在目录
# 启动部署
docker-compose up -d
# 暂停删除
docker-compose down

mongo用户、权限、分片配置

  • 进入一个容器
docker exec -it mongo /bin/mongosh
//或
docker exec -it mongodb bash
  • 用户创建
// 登录mongo
mongo admin -u admin -p 123456     -u 后面的是创建容器指定的账号   -p 后面跟的是创建容器指定的密码
// 使用 admin数据库
use admin  
// 创建一个用户
创建一个用户,赋予用户root权限 
db.createUser(
	{
		user:"root",
		pwd:"123456",
		roles:[{role:"userAdminAnyDatabase",db:"admin"}]
	}
);
//尝试使用上面创建的用户信息进行连接。
db.auth('root', '123456');
// 配置副本集
rs.initiate(
            {
              _id: "rs0",
              members: [
                { _id: 0, host: "192.168.1.12:27017" },
                { _id: 1, host: "192.168.1.12:27018" },
                { _id: 2, host: "192.168.1.12:27019" }
              ]
            }
          );
// 移除副本集
host.docker.internal
rs.remove("host.docker.internal:27017")
// 添加副本集
rs.add("192.168.1.12:27017")  
	
// 切换节点查看同步状态
rs.printReplicationInfo()
 
// 查看副本集配置信息
rs.conf()
 
// 查看副本集运行状态
rs.status()
 
// 节点权重设置
	// 主节点设置 
	docker exec --user mongodb -it mongo1 bash
	mongosh -u root -p mongodb@evescn
	cfg = rs.conf()
	// 修改权重
	cfg.members[0].priority=5
	cfg.members[1].priority=3
// 从新配置
rs.reconfig(cfg)

代码DEMO

from pymongo import MongoClient
from datetime import datetime, timedelta 

def find_paged_data(collection, page_num, page_size):
    start = (page_num -1) * page_size
    end = start + page_size
    # 设置时间范围
    start_time = datetime(2023, 10, 1, 0,0,0)
    end_time = datetime(2023, 10, 31, 23, 59, 59, 999999)
    # 查询时间范围内的文档
    query = {"time": {"$gte": start_time, "$lte": end_time}}
    result = collection.find(query).skip(start).limit(page_size)
    return result

if __name__=="__main__":
    loc_client = MongoClient('mongodb://root:123456@localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0&authSource=admin')
    loc_db = loc_client['wfg']
    loc_col = loc_db['wfgInfoCollection'] 
    page_num = 1
    data = find_paged_data(collection=collection, page_num=page_num, page_size=100000)
    for d in datas:
        print(d["_id"])
  • 8
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值