Centos7 搭建 MongoDB-4.0.3-复制集
这里使用docker 搭建复制集的伪分布式集群(所有节点在同一台机器上)
1. 复制集概述
1) 简介
一组Mongodb复制集,就是一组mongod进程,这些进程维护同一个数据集合。复制集提供了数据冗余和高等级的可靠性,这是生产部署的基础。
2) 目的
- 保证数据在生产部署时的冗余和可靠性,通过在不同的机器上保存副本来保证数据的不会因为单点损坏而丢失。能够随时应对数据丢失、机器损坏带来的风险。
- 还能提高读取能力,用户的读取服务器和写入服务器在不同的地方,而且,由不同的服务器为不同的用户提供服务,提高整个系统的负载。
3) 机制
- 一组复制集就是一组mongod实例掌管同一个数据集,实例可以在不同的机器上面。实例中包含一个主导(Primary),接受客户端所有的写入操作,其他都是副本实例(Secondary),从主服务器上获得数据并保持同步。
- 主服务器很重要,包含了所有的改变操作(写)的日志。但是副本服务器集群包含有所有的主服务器数据,因此当主服务器挂掉了,就会在副本服务器上重新选取一个成为主服务器。
- 每个复制集还有一个仲裁者(Arbiter),仲裁者不存储数据,只是负责通过心跳包来确认集群中集合的数量,并在主服务器选举的时候作为仲裁决定结果。
4) 架构
基本的架构由3台服务器组成,一个三成员的复制集,三个有数据,或者两个有数据+一个作为仲裁者。
5) primary 选举机制
复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消息,并发起Priamry选举操作,获得『大多数』成员投票支持的节点,会成为Primary,其余节点成为Secondary。
- 大多数: 假设复制集内投票成员数量为N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法选举出Primary,复制集将无法提供写服务,处于只读状态。
2. 复制集搭建
1) 拉取mongodb 镜像
docker pull mongo:4.0.3
2) 创建容器
创建三个容器 mongo01, mongo02, mongo03
#创建3个mongo容器
docker create --name mongo01 -p 27017:27017 -v /data/mongo-data-01:/data/db mongo:4.0.3 --replSet "rs0" --bind_ip_all
docker create --name mongo02 -p 27018:27017 -v /data/mongo-data-02:/data/db mongo:4.0.3 --replSet "rs0" --bind_ip_all
docker create --name mongo03 -p 27019:27017 -v /data/mongo-data-03:/data/db mongo:4.0.3 --replSet "rs0" --bind_ip_all
–name: 容器名称
-p: 端口映射
-v: 数据目录挂载
–replSet: 集群id
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVbp6tiK-1593333568685)(./02.png)]
3) 启动容器
docker start mongo01 mongo02 mongo03
4) 连接到其中一个 mongodb容器中
这里连接 mongo01
# 进入到其中一个容器中
docker exec -it mongo01 /bin/bash
# 连接其中一个 mongodb 服务
mongo 192.168.59.131:27017
5) 集群初始化配置
rs.initiate({
_id : "rs0",
members: [
{ _id: 0, host: "192.168.59.131:27017" },
{ _id: 1, host: "192.168.59.131:27018" },
{ _id: 2, host: "192.168.59.131:27019" }
]
})
可见mongo01 角色由 SECONDARY 变为了PRIMARY
6) 集群状态查看
# 利用mongo shell 查看
rs.status()
7) 数据同步测试
mongodb 复制集中,只有Primary接受客户端所有的写入操作,其他都是副本实例Secondary,从主服务器上获得数据并保持同步,只提供读取操作
1.在 Primary 中插入一条数据, 这里是 mongod01
use test
db.user.insert({name: 'lisi'})
2.在 Secondary 中查询数据, 这里是 mongod02, mongod03
进入到 mongo02 容器
# 进入到 mongo02 容器
docker exec -it mongo02 /bin/bash
# 连接 mongodb02
mongo 192.168.59.131:27018
3.查询数据
use test
db.user.find()
4.报错解决
注:
初始情况下, secondary 读和写的操作都无法进行
rs.slaveOk()
db.user.find()
5.mongo03 同样操作
8) arbiter(仲裁者)
当集群中的节点数为
偶数时
,如一主一从情况下,任意一节点宕机都无法选举出Priamry(不满足 N/2 +1
),无法提供写操作,加入arbiter节点后即可解决该问题
- 添加arbiter节点后,如果集群节点数不满足N/2+1时,arbiter节点可作为“凑数”节点,可以选出主节点,继续提供服务。
1.创建一个新的容器
docker create --name mongo04 -p 27020:27017 -v /data/mongo-data-04:/data/db mongo:4.0.3 --replSet "rs0" --bind_ip_all
2.在 primary 节点添加 arbiter
rs.addArb("192.168.59.131:27020")