复制是一种在多个服务器上同步数据的过程。通过在不同的数据库服务器上实现多个数据副本,复制能够实现数据冗余,提高数据的可用性,从而避免了仅仅因为一台服务器故障后就会产生的数据库灾难。总之,复制可以使你免受硬件故障与服务中断的影响,及时恢复数据。由于数据有多个副本,所以可以将其中一个副本用于灾难恢复、报告或备份。
为什么需要复制
- 保持数据安全
- 保证数据的高可用性(24 小时 × 7 天,全年无休)
- 灾难恢复
- 无需停机维护(比如进行备份、索引重建,压缩等任务)
- 读取的可扩展性(可读取其他副本)
- 副本集对应用的公开性
复制在 MongoDB 中的运作方式
MongoDB 使用副本集(replica set)来实现复制操作。副本集是一组托管同一数据集的 mongod 对象。在副本集中,主节点负责接收写入操作。所有其他的实例(从节点)则通过执行主节点的操作来拥有同样的数据集。副本集中只有一个主节点。
- 副本集具有 2 个或多个节点(但一般最少需要 3 个节点)。
- 副本集只有一个主节点,其他全是从节点。
- 所有数据都是从主节点复制到从节点上的。
- 当发生自动故障转移或维护时,会重新推举一个新的主节点。
- 当失败节点恢复后,该节点重新又连接到副本集中,重新作为从节点。
下图展示了一个典型的 MongoDB 复制图。客户端应用总是跟主节点交互,主节点将数据复制到从节点上。
副本集特点
- 具有 N 个节点的集群
- 任何节点都可能成为主节点
- 所有写入操作必须由主节点来完成
- 自动故障转移
- 自动故障恢复
- 重新推举主节点
建立副本集
在本教程中,我们将把单独的一个 mongod 实例转变为副本集,步骤如下:
-
关闭正在运行的 MongoDB 服务器。
-
指定 --replSet 选项来开启 MongoDB 服务器。--replSet 的基本格式如下:
mongod --port "PORT" --dbpath "YOUR_DB_DATA_PATH" --replSet "REPLICA_SET_INSTANCE_NAME"
范例
mongod --port 27017 --dbpath "D:\set up\mongodb\data" --replSet rs0
该命令会在端口 27017 处启动一个名为 rs0 的 MongoDB 实例。在命令行提示符上输入命令连接到该 MongoDB 对象上。在 MongoDB 客户端使用 rs.initiate()
命令来初始化一个新的副本集。检查该副本集设置,则需使用 rs.conf()
。检查副本集状态使用 rs.status()
。
为副本集添加成员
为了向副本集添加成员,在多台机器上开启多个 MongoDB 实例。开启一个 MongoDB 客户端,然后使用 rs.add()
命令。
语法格式
基本的 rs.add()
命令语法格式如下所示:
>rs.add(HOST_NAME:PORT)
范例
假设 MongoDB 实例名称为 mongodb1.net,且运行在 27017 端口处。为了将该实例添加到副本集中,请在 MongoDB 客户端中使用 rs.add()
。
>rs.add("mongod1.net:27017")
>
只有当连接到主节点上时,才能向副本集中添加 MongoDB 实例。要想查看是否连接的是主节点,请在 MongoDB 客户端上使用 db.isMaster()
命令。