0%

MongoDB 副本集搭建(一主一辅一仲裁)

数据复制的意义

    在一个独立部署中,如果 mongod不可用,那么将面临所有数据丢失的风险,这对于生产环境来说是不可接受的。复制被用于提供针对这类数据丢失的安全保障。
    通过将数据复制到不同的节点上,复制提供了数据冗余,因而也就为节点故障的情
况提供了数据保护。在MongoDB部署中,复制提供了高可用性。
    复制还简化了某些管理任务,因此像备份这样的例行任务就可以被转移到复制副本,让主副本可以解脱出来应对重要的应用程序请求。
    在某些应用场景中,通过让客户端读取不同的数据副本,它还可以有助于扩展读取规模。

副本集

    副本集是传统主/从复制的一种复杂形式,简单来说就是集群当中包含了多份数据,保证主副本挂掉了,辅助副本能继续提供数据服务,结构如下:
replica set architecture

上图中包含如下几个MongoDB角色:

  • 主副本(M):副本集只能有一个主副本,客户端会将所有写操作重定向到主副本,然后它会被复制到辅助副本成员;
  • 辅助副本(S):辅助副本成员会保留数据副本,在主副本发生故障转移时会成为主副本的候选;
  • 仲裁者(A):不保留数据副本,所以绝不会成为主副本,仅被用作参与选举主副本的成员。

    这里之所以有一个仲裁节点是因为主副本的选举成功的条件是获得多数票并且获得总票数的过半票数,所以最好是保证有奇数个节点参与选举,关于MongoDB选举机制这里不做深究,大家如果感兴趣可以自行阅读 《MongoDB实战+架构、开发与管理》 7.4.2 副本集 。

环境

CentOS 7.6 64位
MongoDB 3.6.3

MongoDB 安装方法可以参考: Centos 7 离线安装 MongoDB 3.6.3

这里是通过单台机器模拟三个MongoDB节点的方式实现的,和多台机器部署的原理是一致的。

搭建过程

创建数据文件夹

1
2
3
# mkdir -p /data/mongodb/master/{db,logs,conf}
# mkdir -p /data/mongodb/slaver/{db,logs,conf}
# mkdir -p /data/mongodb/arbiter/{db,logs,conf}

配置文件

主副本
文件路径:/data/mongodb/master/conf/mongodb.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 数据存放目录
dbpath=/data/mongodb/master/db
# 存放日志路径, 要先把目录新建好
logpath=/data/mongodb/master/logs/mongodb.log
# 布尔值, 是否追加方式记录日志
logappend=true
# mongodb绑定的ip地址,127.0.0.1只允许本机访问,如果想让其他主机能访问请修改为0.0.0.0
bind_ip=0.0.0.0
# 端口号,默认为27017
port=27001
# 设置oplog的大小(MB)
oplogSize=10000
# 以后台方式运行进程
fork=true
# 启用日志文件,默认启用,生产环境强烈推荐打开
journal=true
# 副本集
replSet = myReplSet

辅助副本
文件路径:/data/mongodb/slaver/conf/mongodb.conf

1
2
3
4
5
6
7
8
9
dbpath=/data/mongodb/slaver/db
logpath=/data/mongodb/slaver/logs/mongodb.log
logappend=true
bind_ip=0.0.0.0
port=27002
oplogSize=10000
fork=true
journal=true
replSet = myReplSet

仲裁者
文件路径:/data/mongodb/arbiter/conf/mongodb.conf

1
2
3
4
5
6
7
8
9
dbpath=/data/mongodb/arbiter/db
logpath=/data/mongodb/arbiter/logs/mongodb.log
logappend=true
bind_ip=0.0.0.0
port=27003
oplogSize=10000
fork=true
journal=true
replSet = myReplSet

三个节点的配置文件大致是相同的,只有dbpathlogpathport不同,
注意replSet字段,要确保同一副本集中所有成员的值全部相同,这里给我们的副本集取名”myReplSet”

启动 MongoDB 服务

注意下面命令中/usr/local/mongodb/是我的MongoDB安装路径

1
2
3
4
# cd /usr/local/mongodb/bin
# ./mongod --config /data/mongodb/master/conf/mongodb.conf
# ./mongod --config /data/mongodb/slaver/conf/mongodb.conf
# ./mongod --config /data/mongodb/arbiter/conf/mongodb.conf

配置主,备,仲裁节点

三个节点中选择一个节点登入MongoDB

1
# mongo 127.0.0.1:27001

然后执行如下命令

1
2
3
4
5
> config = {_id: "myReplSet", members: []}
> config.members.push({_id: 0, host: "172.16.22.30:27001", priority: 2})
> config.members.push({_id: 1, host: "172.16.22.30:27002", priority: 1})
> config.members.push({_id: 2, host: "172.16.22.30:27003", arbiterOnly: true})
> rs.initiate(config)

关键参数说明:
_id: "myReplSet" 中的”myReplSet”是副本集的名称
priority 优先级,默认为1,优先级为0的节点是被动节点,只能保留主副本的数据但是永远不会成为主副本,优先级不为0的节点按照由大到小选出主副本
arbiterOnly 仲裁节点,只参与投票,不保留主副本数据,也不能成为主副本

确认副本集状态

在任意一个副本集的节点执行rs.status(),如下内容只保留了一些关键数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{
"set" : "myReplSet",
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.16.22.30:27001",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
},
{
"_id" : 1,
"name" : "172.16.22.30:27002",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
},
{
"_id" : 2,
"name" : "172.16.22.30:27003",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
}
],
}

myStatestate的值表明了该成员的状态,它可以具有如下所示的值:

myState / state 说明
0 阶段1,启动
1 主节点成员
2 辅助节点成员
3 恢复状态
4 致命错误状态
5 阶段2,启动
6 未知状态
7 仲裁者成员
8 关闭或无法连接
9 一个写操作从主节点迁移成辅助接点之后被该节点回滚
10 当副本集移出成员时,该成员就会进入这个状态

至此为止一个三节点(一主一辅一仲裁)的副本集已经搭建完成

参考

《MongoDB实战+架构、开发与管理》 7.4.2 副本集