NoSQL数据库的最大优势在于很好的支持了集群,今天就准备用MongoDB来配置一个主从服务器。
关于MongoDB的安装就不介绍了,本人使用的是Mac端的MongoDB,版本3.4.9
MongoDB的主从有两种模式,一种是早期的master-slave模式,还有就是后续出来的replica-set模式,一般推荐使用replica-set模式,因为该模式如果master节点挂了,其余的节点会进行选举,选出下一个primary节点,容错性大大提升。
下面就开始配置一个replica-set节点集。主要有三个节点:
127.0.0.1:29010,primary
127.0.0.1:29011,secondary
127.0.0.1:29012,secondary
先来构建目录,我在Mac下的目录结构:
根目录为/data/replica-project,根目录下有三个子目录,分别为:
log,存放日志;
data,存放数据;
config,存放启动配置;
在config目录下,存放三个节点的配置文件:
r0.conf:
#数据文件夹
dbpath=/data/replica-project/data/r0
#日志文件夹,如果以后台方式运行,必须指定logpath
logpath=/data/replica-project/log/r0.log
#以追加而非覆盖方式写入日志
logappend=true
#端口
port=29010
#以后台方式运行
fork=true
r1.conf:
#数据文件夹
dbpath=/data/replica-project/data/r1
#日志文件夹,如果以后台方式运行,必须指定logpath
logpath=/data/replica-project/log/r1.log
#以追加而非覆盖方式写入日志
logappend=true
#端口
port=29011
#以后台方式运行
fork=true
r2.conf:
#数据文件夹
dbpath=/data/replica-project/data/r2
#日志文件夹,如果以后台方式运行,必须指定logpath
logpath=/data/replica-project/log/r2.log
#以追加而非覆盖方式写入日志
logappend=true
#端口
port=29012
#以后台方式运行
fork=true
然后分别启动上述三个节点:
sudo mongod -f /data/replica-project/config/r0.conf --replSet "rs0"
sudo mongod -f /data/replica-project/config/r1.conf --replSet "rs0"
sudo mongod -f /data/replica-project/config/r2.conf --replSet "rs0"
结果如下:
接着我们需要登录想要作为primary节点的机器:
mongo --port 29010
然后配置replica-set:
在刚才登录的shell中定义一个配置对象:
config={_id:"rs0", members:[{_id:0,host:"localhost:29010",priority:1}]}
这里设置priority为1,那么这个机器就会被选举为primary的节点。
调用rs的API进行初始化set:
rs.initiate(config)
可以看到,这里和登录普通的mongod的命令提示符不同,这里有rs0前缀,表明是一个replica-set。但是我们不是设置其为primary了吗?怎么是secondary?别急还没选举出来。我们可以使用命令
rs.conf()
查看我们刚才的配置:
这次提示符变为了primary,说明这个节点已经被推举为了master。master或者priamry节点的特殊性在于,set中至多会有一个primary节点,只有primary节点可以配置set的节点,比如增加和删除,也只有primary节点用于添加或者更新数据,secondary节点只能读取数据。
接着我们需要添加其他的节点到这个set中:
rs.add("localhost:29011")
rs.add("localhost:29012")
使用命令查看当前set集群的状态:
rs.status()
结果为:
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2017-10-03T01:18:55.080Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "localhost:29010",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 470,
"optime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
"electionTime" : Timestamp(1506993212, 2),
"electionDate" : ISODate("2017-10-03T01:13:32Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 1,
"name" : "localhost:29011",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 43,
"optime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
"optimeDurableDate" : ISODate("2017-10-03T01:18:54Z"),
"lastHeartbeat" : ISODate("2017-10-03T01:18:54.457Z"),
"lastHeartbeatRecv" : ISODate("2017-10-03T01:18:53.457Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "localhost:29010",
"configVersion" : 3
},
{
"_id" : 2,
"name" : "localhost:29012",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 38,
"optime" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1506993534, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-10-03T01:18:54Z"),
"optimeDurableDate" : ISODate("2017-10-03T01:18:54Z"),
"lastHeartbeat" : ISODate("2017-10-03T01:18:54.457Z"),
"lastHeartbeatRecv" : ISODate("2017-10-03T01:18:53.650Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "localhost:29010",
"configVersion" : 3
}
],
"ok" : 1
}
从这里可以看到配置成功了。
下面我们来验证一下主从服务器,在主库里面插入一条数据,然后在从库里面读取。
在主库插入一条数据:
use test
db.test.insert({name:"liyao", age:25})
登录一台secondary服务器:
mongo --port 29011
然后尝试读取:
use test
db.test.find()
出现了如下信息:
这是因为默认只能对主库进行操作,如果想从从库读取,必须使用下面的命令设置:
db.setSlaveOk()
这时就可以查询了。
至此,一个简单的MongoDB主从构架就配置好了。