复制

MongoDB数据库在实际生产环境下,多数基于多服务器集群运行,并进行相应的数据分布式处理。因此,必须考虑数据读写的可用性和安全性,如一台服务器出故障时,应该能保证MongoDB数据处理的正常进行。

复制(Replication,在MongoDB数据库里又称“副本集”①)就是为解决上述问题而产生的,通过复制功能可以实现多服务器的数据冗余备份操作;使备份数据的服务器具备额外提供独立读访问请求的功能(分布式读取数据,可以解决高并发客户端读用户访问问题);当服务器出故障时,提供自动故障转移、自动数据恢复。

1、复制基本原理

在执行复制动作之前,需要先在不同服务器中安装Mongod实例(通常一个服务器安装一个mongod.exe程序)。一个典型副本集包括了几个数据保存节点(这里把一个节点看 作一台服务器),并可以选择另外一个独立节点作为副本集数据复制管理的仲裁节点(Arbiter Node)。在副本集中,只有一个是主节点(Primary Node),其他几个是从节点 (Secondary Node)。一般情况下一个副本集至少需要3个节点(一主二从),如图所示。

主节点负责接收客户端写入数据操作(默认情况下主节点也承担了读的任务,在大访问量情况下,存在访问瓶颈问题)。从节点负责从主节点复制数据,以保证主从节点数据的一致性和安全性。复制依据为本地的Oplog(复制操作日志local.oplog.rs)集合。主节点与从节点进行同步Oplog更新。当副本集只有偶数个节点时,可以增加仲裁节点。作为仲裁节点的服务器只装mongod.exe程序,不承担数据副本的存储任务。仲裁节点通过心跳(Hearbeat)功能保持与 其他节点的联系,一旦主节点出故障,就进行新主节点选举投票,确保新的主节点及时产生并工作。

2、搭建副本集

单机环境搭建一个1主2从的副本集。

新建文件夹,为各个实例存放数据和日志文件还有配置文件:

角色数据日志配置文件主(127.0.0.1:27017)/data/log/etc/mongod.yaml从1(127.0.0.1:27018)/data1/log1/etc1/mongd1.yaml从2(127.0.0.1:27019)/data2/log2/etc2/mongd2.yaml

#主配置 mongod.yaml

net:

bindIp: 127.0.0.1

port: 27017

processManagement:

fork: true

systemLog:

destination: file

path: "/usr/local/mongodb-macos-x86_64-5.0.17/log/mongo.log"

logAppend: true

storage:

dbPath: "/usr/local/mongodb-macos-x86_64-5.0.17/data"

replication:

replSetName: "myapp" #副本集名称

#从1配置 mongod1.yaml

net:

bindIp: 127.0.0.1

port: 27018

processManagement:

fork: true

systemLog:

destination: file

path: "/usr/local/mongodb-macos-x86_64-5.0.17/log1/mongo.log"

logAppend: true

storage:

dbPath: "/usr/local/mongodb-macos-x86_64-5.0.17/data1"

replication:

replSetName: "myapp" #副本集名称

#从2配置 mongod2.yaml

net:

bindIp: 127.0.0.1

port: 27019

processManagement:

fork: true

systemLog:

destination: file

path: "/usr/local/mongodb-macos-x86_64-5.0.17/log2/mongo.log"

logAppend: true

storage:

dbPath: "/usr/local/mongodb-macos-x86_64-5.0.17/data2"

replication:

replSetName: "myapp" #副本集名称

启动3个实例:

mongod -f ./etc/mongod.yaml

mongod -f ./etc1/mongod1.yaml

mongod -f ./etc2/mongod2.yaml

设置集群配置文件: 在任意一个启动的Mongo上设置下配置信息,然后初始化 mongo -port 27017

use admin

config = {

_id: "myapp",

members: [

{_id: 0, host: "127.0.0.1:27017", "priority": 3},

{_id: 1, host: "127.0.0.1:27018", "priority": 2},

{_id: 2, host: "127.0.0.1:27019", "priority": 1}

]

}

//初始化命令

rs.initiate(config)

测试:db.isMaster() 测试:rs.conf()查看副本集配置对象内容

连接从1节点:mongo -port 27018 查询数据报错: 备份节点可能会落后于主节点,可能没有最新写入的数据,所以备份节点在默认情况下会拒绝读取请求,以防止应用程序意外拿到过期的数据。因此,如果在备份节 点上做查询,可能会得到一个错误提示,说当前节点不是主节点。

这是为了保护应用程序,以免意外连接到备份节点,读取到过期数据。如果希望从备份节点读取数据,需要设置“从备份节点读取数据没有问题”标识,如下所示:

rs.secondaryOk()

在主库插入一条数据: 从库查询:

从库写入数据:

可以看到,不能对备份节点执行写操作。备份节点只通过复制功能写入数据,不接受客户端的写入请求。

推荐文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: