04. 复制
MongoDB Replication
一、副本集
1.1 复制功能
为保证数据安全,实现高可用,

复制过程如下:
1. 初始同步
在副本集初始化时,主节点的
2. 同步复制
从节点在初始化完成后,不断同步地复制主节点的
3. 异步执行
1.2 仲裁者
除了可以将正常的
虽然仲裁者可以占用更少的服务器资源,但是由于其并不存储数据,所以对数据的安全性并不能起到帮助作用。因此应该尽量避免使用仲裁者,同时尽量保证最多只使用一个仲裁者,即如果节点数量恰好是偶数,则添加一个仲裁者,如果节点数量是奇数,那就不需要仲裁者。

二、故障发现与恢复
2.1 故障发现
副本集的每个节点之间会维持着两秒一次的心跳检测,当从节点与主节点的通信时间超过配置的
2.2 优先选举

2.3 投票成员
节点发起选举后,需要具有投票权的节点进行投票,当获得半数以上选票时,该备用节点可以成为新的主节点。对于一个复制集,只有处于以下状态的节点拥有投票权,这些节点统称为投票成员:
- PRIMARY:副本集的主节点。
- SECONDARY:处于复制状态的从节点。
- STARTUP2:
mongod 完成配置加载后,副本集的每个成员都进入STARTUP2 状态,此时它成为副本集的活动成员并且有资格投票。然后该成员决定是否进行初始同步。如果成员开始初始同步,则成员将保留在STARTUP2 状态,直到所有数据复制完成并构建好索引。之后成员过渡到RECOVERING 。 - RECOVERING:当副本集的成员尚未准备好接受读取操作时,它将进入
RECOVERING 状态。处于恢复状态的成员有资格在选举中投票,但没有资格成为主节点。 - ARBITER:
ARBITER 状态的成员不复制数据或接受写入操作,仲裁者通常处于这一状态。 - ROLLBACK:如果成员正在进行数据回滚,它就处于
ROLLBACK 状态。
除了投票成员外,那些持有副本集数据的副本,并且可以接受来自客户端应用程序的读取操作,但没有投票权的成员统称为非投票成员。出于网络通讯成本的考虑,
- 非投票成员的优先级
members[n].priority
必须为0 ,优先级为0 的成员不能寻求选举,也不能成为主节点。 - 优先级大于
0 的节点持有的票数members[n].votes
不能为0 ,该参数默认值为1 ,可选值为1 或0 。
如下示例是一个

三、搭建副本集
这里以搭建一个三节点的副本集为例,使用三台服务器,主机名分别为
3.1 下载并解压
选择所需版本的

这里我下载的版本为4.0.10
RHEL 7.0
,下载后进行解压:
tar -zxvf mongodb-linux-x86_64-rhel70-4.0.10.tgz -C /usr/app
3.2 配置环境变量
配置环境变量:
vi /etc/profile
export MONGODB_HOME=/usr/app/mongodb-linux-x86_64-rhel70-4.0.10/
export PATH=${MONGODB_HOME}/bin:$PATH
使得配置的环境变量立即生效:
source /etc/profile
3.3 修改配置
/var/lib/mongo
,默认存放日志的目录为 /var/log/mongodb
,采用/var/
下只能存放临时文件,所以这里我们使用其他目录进行存储,命令如下:
mkdir -p /home/mongodb/data
mkdir -p /home/mongodb/log
修改配置,采用
vim /etc/mongod.conf
在配置文件中增加如下配置,这里的配置采用的是
processManagement:
# 以后台进程的方式启动
fork: true
systemLog:
destination: file
path: "/home/mongodb/log/mongod.log"
logAppend: true
storage:
dbPath: "/home/mongodb/data"
net:
port: 27017
# 如果不修改绑定IP,默认只能在本机访问数据库服务
bindIp: 0.0.0.0
replication:
# 处于同一副本集的所有节点需要保证副本集名称一致
replSetName: rs0
MongoDB 的所有配置项可以参考其官方文档:Configuration File Options
3.4 启动服务
以上配置步骤在三台主机上均相同。之后启动三台主机上的
mongod -f /etc/mongod.conf
3.5 配置副本集
在任意一台主机上使用
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "hadoop001:27017" },
{ _id: 1, host: "hadoop002:27017" },
{ _id: 2, host: "hadoop003:27017" }
]
})
3.6 查看副本集情况
使用 rs.status()
命令查看副本集状态,部分输出如下。从输出中可以看到

参考资料
- 官方文档:https://docs.mongodb.com/manual/replication/
- 官方配置说明:https://docs.mongodb.com/manual/reference/configuration-options/