MongoDB 单机模式改副本集架构(集群搭建)

23

写在前面

将现有 MongoDB 数据库的单机运行模式改造为 一主二从 的副本集(replication Set)高可用运行架构。

副本集模式特性:

  • 保障数据的安全性

  • 数据高可用性 (24*7)

  • 灾难恢复

  • 无需停机维护(如备份,重建索引,压缩)

  • 分布式读取数据

MongoDB 副本集结构图:

结构图

结构图

Mongo 副本集模式官方文档:https://docs.mongodb.com/v4.0/replication

搭建准备

搭建目标:一个主节点、两个从节点(其中一个从节点仅作为数据复制,不参与选举)

搭建目标

搭建目标

当前已安装的 MongoDB 环境:

  • 系统:Ubuntu

  • MongoDB:4.0.25(apt-get install 方式安装)

准备好的三台虚拟机:

虚拟机

HOST

角色

备注

1号机

192.168.1.10:27017

primary

已安装 MongoDB

2号机

192.168.1.11:27017

secondary

用于主节点故障恢复,客户端读操作

3号机

192.168.1.12:27017

secondary

用于数据备份,该节点不参与选举

基于现有的 MongoDB 环境,另外两个节点使用 docker 方式快速搭建。

开始

1. 生成各节点通讯时需要的 keyFile 安全认证文件

1号机 上执行生成命令:

sudo openssl rand -base64 741 >> mongo_auth.key

将 mongo_auth.key 文件下载到本地,后面将会上传到另外两个节点的虚拟机上。

2. 搭建另外两个 MongoDB 节点

2号机3号机 上执行以下操作;

创建目录结构:

mkdir ~/docker/mongo/conf -p
mkdir ~/docker/mongo/db -p

将第1步中创建的 keyFile 文件上传到 ~/docker/mongo/conf 目录下,并执行命令:

sudo chmod 600 ~/docker/mongo/conf/mongo_auth.key
sudo chown 999 ~/docker/mongo/conf/mongo_auth.key

创建 MongoDB 的配置文件:

sudo vim ~/docker/mongo/conf/mongod.conf

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0

# 安全
security:
  authorization: enabled # 开启访问认证
  clusterAuthMode: keyFile # 集群认证模式
  keyFile: /etc/mongo/mongo_auth.key

# 副本集
replication:
   replSetName: "rs" # 副本集名称

使用 Docker 运行 MongoDB:

docker run --name mongo -p 27017:27017 -v /home/newton-dev/docker/mongo/db:/data/db -v /home/newton-dev/docker/mongo/conf:/etc/mongo -d mongo:4.0.25 --config /etc/mongo/mongod.conf

3. 更改 1号机 MongoDB 的运行模式为副本集模式

调整 keyFile 文件的存放位置:

sudo chmod 600 mongo_auth.key
sudo chown mongodb:mongodb mongo_auth.key
sudo mv mongo_auth.key /data/mongo_auth.key

修改 MongoDB 配置文件:

sudo vim /etc/mongod.conf

# 安全
security:
  authorization: enabled # 开启访问认证
  clusterAuthMode: keyFile # 集群认证模式
  keyFile: /data/mongo_auth.key

# 副本集
replication:
   replSetName: rs # 副本集名称

重启 MongoDB :

sudo systemctl restart mongod

4. 配置副本集

1号机中,登入 MongoDB 客户端,并授权:

user@host:~$ mongo
> use admin
> db.auth('账号', '密码')

初始化副本集:

> rs.initiate({
	_id: "rs",
	members: [
		{ _id: 0, host: "192.168.1.10:27017", priority: 9 },
		{ _id: 1, host: "192.168.1.11:27017", priority: 1 },
		{ _id: 2, host: "192.168.1.12:27017", priority: 0, hidden: true }
	] 
})

rs.initiate() 命令用于初始化副本集,只能执行一次。
其中的参数:

  • _id:副本集名称,同 mongod.conf 中配置的 replSetName;

  • members._id:节点ID,从0开始;

  • members.host:节点 IP:端口;

  • members.priority:选举优先级,范围是0-100,值越大,优先权越高,为0将不参与选举;

  • members.hidden:false 时该节点将对客户端不可见;

更多详见:https://docs.mongodb.com/v4.0/reference/method/rs.initiate

其他:

查看副本集状态:

rs.status()

查看副本集配置:

rs.config()

调整节点配置:(主节点上执行)

cfg=rs.conf()
cfg.members[1].priority=2
rs.reconfig(cfg)

客户端连接

连接uri示例:

mongodb://账号:密码@[节点IP:端口],[节点IP:端口]/数据库名称?authSource=admin&slaveOk=true&replicaSet=副本集名称&write=1&readPreference=secondaryPreferred&connectTimeoutMS=300000

参数说明 - readPreference 的可选值:

  • primary (只主)只从 primary 节点读数据,这个是默认设置

  • primaryPreferred (先主后从)优先从 primary 读取,primary 不可服务,从 secondary 读

  • secondary (只从)只从 scondary 节点读数据

  • secondaryPreferred (先从后主)优先从 secondary 读取,没有 secondary 成员时,从 primary 读取

  • nearest (就近)根据网络距离就近读取,根据客户端与服务端的PingTime实现

readPreference 控制客户端 Driver 从复制集的哪个节点读取数据,这个特性可以方便的配置读写分离、就近读取等策略。结合Tag,可以进一步细分控制读取策略。