MongoDB在单节点中也可以做复制集,但是仅限于测试实验,最大的好处就是部署方便快速,可以随便添加新节点,节省资源。在这里我使用的是MongoDB 2.6版本进行复制集实验(但MongoDB配置文件使用的是老版本格式),一共使用三个节点,一个是主节点(PRIMARY),一个是从节点(SECONDARY),一个是投票节点(ARBITER)。如下图:
一、实验环境
1)节点信息:192.168.60.60
3)节点确保iptables和selinux已关闭
1 2 |
[root@node1 ~]# iptables -F [root@node1 ~]# setenforce 0 |
二、安装MongoDB 2.6
1 2 3 4 5 |
mongodb-org-mongos-2.6.0-1.x86_64.rpm mongodb-org-tools-2.6.0-1.x86_64.rpm mongodb-org-server-2.6.0-1.x86_64.rpm mongodb-org-shell-2.6.0-1.x86_64.rpm mongodb-org-2.6.0-1.x86_64.rpm |
PS:需要的软件包可以去http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/下载,MongoDB的安装很简单,怎么安装都成。
三、配置单点复制集(启动三个套接字)
1)创建所需要的目录
1 2 3 4 5 6 |
[root@node3 ~]# mkdir -p /mongodb/{conf,log,pid,data} [root@node3 ~]# mkdir -p /mongodb/conf/{conf27017,conf27018,conf27019} [root@node3 ~]# mkdir -p /mongodb/log/{log27017,log27018,log27019} [root@node3 ~]# mkdir -p /mongodb/pid/{pid27017,pid27018,pid27019} [root@node3 ~]# mkdir -p /mongodb/data/{data27017,data27018,data27019} [root@node3 ~]# chown -R mongod.mongod /mongodb/data/{data27017,data27018,data27019} |
2)创建三个配置文件
192.168.60.60:27017
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
[root@node3 ~]# vi /mongodb/conf/conf27017/mongod.conf ###Base configure logpath = /mongodb/log/log27017/mongod.log logappend = true dbpath = /mongodb/data/data27017 port = 27017 bind_ip=192.168.60.60 fork = true pidfilepath = /mongodb/pid/pid27017/mongod.pid logRotate = rename timeStampFormat = ctime #Replica Set oplogSize = 1024 replSet = ywnds replIndexPrefetch = _id_only PS:具体参数含义请看《MongoDB命令行选项介绍》 |
192.168.60.60:27018
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@node3 ~]# vi /mongodb/conf/conf27018/mongod.conf ###Base configure logpath = /mongodb/log/log27018/mongod.log logappend = true dbpath = /mongodb/data/data27018 port = 27018 bind_ip=192.168.60.60 fork = true pidfilepath = /mongodb/pid/pid27018/mongod.pid logRotate = rename timeStampFormat = ctime #Replica Set oplogSize = 1024 replSet = ywnds replIndexPrefetch = _id_only |
192.168.60.60:27019
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
[root@node3 ~]# vi /mongodb/conf/conf27019/mongod.conf ###Base configure logpath = /mongodb/log/log27019/mongod.log logappend = true dbpath = /mongodb/data/data27019 port = 27019 bind_ip=192.168.60.60 fork = true pidfilepath = /mongodb/pid/pid27019/mongod.pid logRotate = rename timeStampFormat = ctime #Replica Set oplogSize = 1024 replSet = ywnds replIndexPrefetch = _id_only |
3)启动集群(所有节点)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@node3 mongodb]# killall mongod [root@node3 mongodb]# mongod -f /mongodb/conf/conf27019/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 35554 child process started successfully, parent exiting [root@node3 mongodb]# mongod -f /mongodb/conf/conf27018/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 35601 child process started successfully, parent exiting [root@node3 mongodb]# mongod -f /mongodb/conf/conf27017/mongod.conf about to fork child process, waiting until server is ready for connections. forked process: 35648 child process started successfully, parent exiting |
查看进程
1 2 3 4 |
[root@node3 ~]# netstat -anplt | grep mongod tcp 0 0 192.168.60.60:27019 0.0.0.0:* LISTEN 35554/mongod tcp 0 0 192.168.60.60:27017 0.0.0.0:* LISTEN 35648/mongod tcp 0 0 192.168.60.60:27018 0.0.0.0:* LISTEN 35601/mongod |
4)选择一个节点做主节点(可以随意选择一个,这里我使用21017)
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27017/admin MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27017/admin > |
5)初始化27017节点
5.1.为复制集初始化建立配置文档
1 2 3 4 5 6 7 |
> config = { _id:"ywnds", members:[ {_id:0,host:"192.168.60.60:27017"}, {_id:1,host:"192.168.60.60:27018"}, {_id:2,host:"192.168.60.60:27019"} ]} |
5.2.更新配置文档参数,设置27019为arbiterOnly(投票节点)
1 |
> config.members[2] = {"_id":2,"host":"192.168.60.60:27019","arbiterOnly":true} |
PS:上面是把复制集初始化配置文档赋值给config变量,这里是通过membes数组的索引来修改节点属性,数组索引从0开始。
具体的配置文档说明请看《MongoDB复制集配置文档介绍》
5.3.使用rs.initiate(cfg)初始化集群
1 2 3 4 5 |
> rs.initiate(config) { "info" : "Config now saved locally. Should come online in about a minute.", "ok" : 1 } |
这里使用rs.initiate(config)初始化集群,config文件为我们上面定义的。这里的ok返回值为1表示命令执行成功,如果为0则表示没有执行成功。跟Linux中的状态值刚好相反。现在可以使用rs.conf()方法返回配置文件内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
ywnds:PRIMARY> rs.conf() { "_id" : "ywnds", "version" : 1, "members" : [ { "_id" : 0, "host" : "192.168.60.60:27017" }, { "_id" : 1, "host" : "192.168.60.60:27018" }, { "_id" : 2, "host" : "192.168.60.60:27019", "arbiterOnly" : true } ] } |
5.4.查看集群状态
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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
ywnds:PRIMARY> rs.status() { "set" : "ywnds", "date" : ISODate("2016-02-03T01:56:49Z"), "myState" : 1, "members" : [ { "_id" : 0, "name" : "192.168.60.60:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1043, "optime" : Timestamp(1454464583, 1), "optimeDate" : ISODate("2016-02-03T01:56:23Z"), "electionTime" : Timestamp(1454464592, 1), "electionDate" : ISODate("2016-02-03T01:56:32Z"), "self" : true }, { "_id" : 1, "name" : "192.168.60.60:27018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 25, "optime" : Timestamp(1454464583, 1), "optimeDate" : ISODate("2016-02-03T01:56:23Z"), "lastHeartbeat" : ISODate("2016-02-03T01:56:48Z"), "lastHeartbeatRecv" : ISODate("2016-02-03T01:56:47Z"), "pingMs" : 2, "syncingTo" : "192.168.60.60:27017" }, { "_id" : 2, "name" : "192.168.60.60:27019", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 25, "lastHeartbeat" : ISODate("2016-02-03T01:56:48Z"), "lastHeartbeatRecv" : ISODate("2016-02-03T01:56:47Z"), "pingMs" : 0 } ], "ok" : 1 } |
我们的集群中有三个节点,由状态返回值可以看出27017为PRIMARY节点,而27018为SECONDARY节点,而27019为我们设置的ARBITER节点。这里我们发现mongodb的角标已经变了,变成了复制集名称加上当前节点的状态。同样如果登陆27018和27019会发现都发生了变化。
5.5.查看主节点local库
1 2 3 4 5 6 7 8 9 |
ywnds:PRIMARY> use local switched to db local ywnds:PRIMARY> show tables me oplog.rs slaves startup_log system.indexes system.replset |
这里我们看一下本地的local库,每一个mongod实例都有自己的local数据库,其中存储了复制进程所用的数据和其他实例单独的信息,local数据库对于复制时不可见的,local数据库将不会被复制。
进入到local库可以看到一些集合和索引文件,其中startup_log 是一个固定集合,该集合主要是用来诊断的(每个mongod 实例向 startup_log 插入一条有关mongod实例自身和host信息的诊断信息);system.replset保存了复制集的配置文档信息(就是我们上面定义的config),跟rs.conf()返回的信息一样;oplog.rs是一个存储了oplog的固定集合,大小为我们在配置文件中设置的大小;slaves包含了复制集每个节点和与其通讯的最后时间戳。如果该集合过时了,我们可以通过删除该节点来让复制集自动刷新生成。
6)验证复制集
192.168.60.60:27017插入数据
1 2 3 4 5 6 7 |
[root@node3 ~]# mongo 192.168.60.60:27017 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27017/test ywnds:PRIMARY> use ywnds switched to db ywnds ywnds:PRIMARY> db.ywnds.insert({name:"ywnds",age:"20",gender:"B"}) WriteResult({ "nInserted" : 1 }) |
然后我们来看一下主节点的数据目录(MMAPV1存储引擎为例):
1 2 3 4 5 6 7 8 9 |
[root@node3 ~]# ll -h /mongodb/data/data27017/ 总用量 2.2G drwxr-xr-x. 2 mongod mongod 4.0K 2月 4 07:58 journal -rw-------. 1 mongod mongod 64M 2月 4 07:58 local.0 -rw-------. 1 root root 2.0G 2月 3 11:31 local.1 -rw-------. 1 mongod mongod 16M 2月 4 07:58 local.ns -rwxr-xr-x. 1 mongod mongod 6 2月 4 07:58 mongod.lock -rw-------. 1 root root 64M 2月 3 11:31 ywnds.0 -rw-------. 1 root root 16M 2月 3 11:31 ywnds.ns |
这里我们可以看到,local数据库的物理文件local.0和local.1。Mongodb默认第一个物理文件为64M,名字为local.0,然后依次为local.1…N。而local数据库的命名空间文件“local.ns”默认为16M,前面我们在说命令行选项的时候就说过命名空间文件,每一个数据库都会有一个命名空间NS文件,记录当前数据库每一个物理文件,如local.0、local.1它们之间的联系,同时也记录当前这个库中每一个集合里的索引信息。
192.168.60.60:27018同步数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[root@node3 ~]# mongo 192.168.60.60:27018 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27018/test ywnds:SECONDARY> show dbs admin (empty) local 2.077GB ywnds 0.078GB ywnds:SECONDARY> use ywnds switched to db ywnds ywnds:SECONDARY> show tables 2016-02-03T11:34:24.505+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } ywnds:SECONDARY> db.ywnds.insert({name:"eric",age:20}) WriteResult({ "writeError" : { "code" : undefined, "errmsg" : "not master" } }) ywnds:SECONDARY> rs.slaveOk(true) ywnds:SECONDARY> show tables system.indexes ywnds |
我们看到数据已经同步过来了,但是如果我们不是通过驱动连接从节点的话,我们查看数据时会报错,说我们不是master节点,且slaveOK=false,所以查看不了。MongoDB在数据一致性上确实下了很大的功夫啊。那么也就是说如果从节点想查看数据就需要开启slaveOK,并且在从节点上是无法进行写入操作的。
然后我们开启rs.slaveOk立马就可以查看同步的数据了。
192.168.60.60:27019投票节点
1 2 3 4 5 6 7 8 9 10 11 12 13 |
[root@node3 ~]# mongo 192.168.60.60:27019 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27019/test ywnds:ARBITER> show dbs admin (empty) local 0.078GB ywnds:ARBITER> use local switched to db local ywnds:ARBITER> show tables me startup_log system.indexes system.replset |
连接到投票节点,我们可以看到PRIMARY上的数据没有同步到投票节点上来,没有ywnds这个库。但是这里需要说明的是,我们可以看到arbiter虽然不同步数据但是local库却有system.indexes和system.replset这两个文件。其次我们看一下arbiter节点的数据目录。
1 2 3 4 5 6 |
[root@node3 ~]# ll -h /mongodb/data/data27019/ 总用量 81M drwxr-xr-x. 2 mongod mongod 4.0K 2月 3 09:56 journal -rw-------. 1 mongod mongod 64M 2月 3 09:56 local.0 -rw-------. 1 mongod mongod 16M 2月 3 09:56 local.ns -rwxr-xr-x. 1 mongod mongod 6 2月 3 09:39 mongod.lock |
可以发现我们所说的库物理文件的第一个文件默认大小为64M,而命名空间文件为16M。
四、按照功能来区分复制集成员
从上面的分析可以看出三个节点的不同之处,也可以这么说,上面我们是按照数据来区分不同的复制集节点,那么下面我们按照功能上来区分各个节点。先来简单说一下各个节点状态的不同所能提供的功能有哪些?
主节点(PRIMARY):默认提供读写服务的节点。
从节点(SECONDARY):提供读服务的节点,但可以提供多样性服务,如可以转为“隐藏节点”对程序不可见、转为“延时节点”延时复制节点、转为“投票节点”具有投票权但不是arbiter。
投票节点(ARBITER):ARBITER节点,无数据,仅作选举和充当复制集节点、也称它为选举节点。
五、复制集自动容灾
Mongodb复制集最大的特点就是可以自动容灾,这个特性是从主从复制的架构上改变而来,简单来说就是当复制集(3节点)中如果PRIMARY发生故障,其他节点无法探测到它的心跳信息时,复制集就会产生从新投票选出一个新的PRIAMRY提供服务。下面我们来模拟一下MongoDB的自动故障转移功能。
我们连接到27017主机上,此时的27017是PRIMARY
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27017 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27017/test ywnds:PRIMARY> |
我们连接到27018主机上,此时的27018是SECONDARY
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27018 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27018/test ywnds:SECONDARY> |
我们连接到27019主机上,此时的27019是ARBITER
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27019 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27019/test ywnds:ARBITER> |
模拟主节点宕机,kill掉27017的进程。
1 2 3 4 5 6 |
[root@node3 ~]# cat /mongodb/pid/pid27017/mongod.pid 125484 [root@node3 ~]# kill -2 125484 [root@node3 ~]# ps aux | grep mongod root 125581 0.5 7.9 5266620 48252 ? Sl 04:07 0:00 mongod -f /mongodb/conf/conf27018/mongod.conf root 125670 0.5 5.1 849056 31440 ? Sl 04:07 0:00 mongod -f /mongodb/conf/conf27019/mongod.conf |
然后登录27018主机上,看看此时的SECONDARY已经转为PRIMARY了,但是这个过程会有短暂的断开。
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27018 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27018/test ywnds:PRIMARY> |
而27019主机上ARBITER还是ARBITER节点。
1 2 3 4 |
[root@node3 ~]# mongo 192.168.60.60:27019 MongoDB shell version: 2.6.0 connecting to: 192.168.60.60:27019/test ywnds:ARBITER> |
有兴趣可以通过show log rs命令查看复制集的日志信息,看看这个过程是怎么进行的。这就是MongoDB三节点(一主一从一投票或一主二从)复制集的故障转移功能,是不是很强大。当然除了复制集内部自动选举之外,我们也可以进行人工干预,使用rs.stepdown()方法可以手动切换。
原文地址:https://www.cnblogs.com/ExMan/p/9665066.html