二mongodb主从配置
在之前我们使用mysql数据库或者redis时大家广泛用到,采用双机备份后主节点挂掉了后从节点可以接替主机继续服务。所以这种模式比单节点的高可用性要好很多。
1、环境准备
实际应用中,需要两台机器一主一从。我这里因资源问题,使用一台机器解决。
192.168.221.161:27021当做master
192.168.221.161:27022当做slave
2、分别建立两个文件夹/data/db_master,/data/db_slave
3、分别配置两个配置文件mongodb_master.conf,mongodb_salve.conf
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@MidApp mongodb]
# cat mongodb_master.conf
dbpath=
/data/db_master
logpath=
/usr/local/mongodb/logs/mongodb_master
.log
logappend=
true
port=27021
fork=
true
auth=
false
nohttpinterface=
false
bind_ip=192.168.221.161
journal=
true
quiet=
true
master=
true
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
[root@MidApp mongodb]
# cat mongodb_salve.conf
dbpath=
/data/db_slave
logpath=
/usr/local/mongodb/logs/mongodb_slave
.log
logappend=
true
port=27022
fork=
true
auth=
false
nohttpinterface=
false
bind_ip=192.168.221.161
journal=
true
quiet=
true
slave=
true
source
=192.168.221.161:27021
|
4. 启动master节点
1
2
3
4
|
[root@MidApp mongodb]
# mongod -f mongodb_master.conf
about to fork child process, waiting
until
server is ready
for
connections.
forked process: 55489
child process started successfully, parent exiting
|
Master上输出日志内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
2017-11-14T09:02:39.999-0800 I CONTROL [initandlisten] options: { config:
"mongodb_master.conf"
, master:
true
, net: { bindIp:
"192.168.221.161"
, http: { enabled:
true
}, port: 27021 }, processManagement: { fork:
true
}, security: { authorization:
"disabled"
}, storage: { dbPath:
"/data/db_master"
, journal: { enabled:
true
} }, systemLog: { destination:
"file"
, logAppend:
true
, path:
"/usr/local/mongodb/logs/mongodb_master.log"
, quiet:
true
} }
2017-11-14T09:02:40.014-0800 I INDEX [initandlisten] allocating new ns
file
/data/db_master/local
.ns, filling with zeroes...
2017-11-14T09:02:40.018-0800 I NETWORK [websvr] admin web console waiting
for
connections on port 28021
2017-11-14T09:02:40.254-0800 I STORAGE [FileAllocator] allocating new datafile
/data/db_master/local
.0, filling with zeroes...
2017-11-14T09:02:40.254-0800 I STORAGE [FileAllocator] creating directory
/data/db_master/_tmp
2017-11-14T09:02:40.263-0800 I STORAGE [FileAllocator]
done
allocating datafile
/data/db_master/local
.0, size: 64MB, took 0.001 secs
2017-11-14T09:02:40.318-0800 I REPL [initandlisten] ******
2017-11-14T09:02:40.318-0800 I REPL [initandlisten] creating replication oplog of size: 990MB...
2017-11-14T09:02:40.319-0800 I STORAGE [FileAllocator] allocating new datafile
/data/db_master/local
.1, filling with zeroes...
2017-11-14T09:02:40.349-0800 I STORAGE [FileAllocator]
done
allocating datafile
/data/db_master/local
.1, size: 1024MB, took 0.029 secs
2017-11-14T09:02:40.354-0800 I REPL [initandlisten] ******
2017-11-14T09:02:40.358-0800 I NETWORK [initandlisten] waiting
for
connections on port 27021
|
5. 启动从节点
1
2
3
4
|
[root@MidApp mongodb]
# mongod -f mongodb_salve.conf
about to fork child process, waiting
until
server is ready
for
connections.
forked process: 55577
child process started successfully, parent exiting
|
Slave上输出日志如下:
1
2
3
4
5
6
7
8
|
2017-11-14T09:05:10.757-0800 I CONTROL [initandlisten] allocator: tcmalloc
2017-11-14T09:05:10.757-0800 I CONTROL [initandlisten] options: { config:
"mongodb_salve.conf"
, net: { bindIp:
"192.168.221.161"
, http: { enabled:
true
}, port: 27022 }, processManagement: { fork:
true
}, security: { authorization:
"disabled"
}, slave:
true
,
source
:
"192.168.221.161:27021"
, storage: { dbPath:
"/data/db_slave"
, journal: { enabled:
true
} }, systemLog: { destination:
"file"
, logAppend:
true
, path:
"/usr/local/mongodb/logs/mongodb_slave.log"
, quiet:
true
} }
2017-11-14T09:05:10.759-0800 I INDEX [initandlisten] allocating new ns
file
/data/db_slave/local
.ns, filling with zeroes...
2017-11-14T09:05:10.763-0800 I NETWORK [websvr] admin web console waiting
for
connections on port 28022
2017-11-14T09:05:11.039-0800 I STORAGE [FileAllocator] allocating new datafile
/data/db_slave/local
.0, filling with zeroes...
2017-11-14T09:05:11.039-0800 I STORAGE [FileAllocator] creating directory
/data/db_slave/_tmp
2017-11-14T09:05:11.045-0800 I STORAGE [FileAllocator]
done
allocating datafile
/data/db_slave/local
.0, size: 64MB, took 0.001 secs
2017-11-14T09:05:11.066-0800 I NETWORK [initandlisten] waiting
for
connections on port 27022
|
6. 验证一下主从复制
登录master插入数据:
1
2
3
4
5
6
7
8
9
10
11
|
[root@MidApp mongodb]
# mongo 192.168.221.161:27021
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27021
/test
> show dbs
local
1.078GB
> use
test
switched to db
test
> db.testdb.insert({
"test1"
:
"item1"
})
WriteResult({
"nInserted"
: 1 })
> db.testdb.
find
()
{
"_id"
: ObjectId(
"5a0b23702c969986fca777ed"
),
"test1"
:
"item1"
}
|
登录slave节点,验证数据:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[root@MidApp mongodb]
# mongo 192.168.221.161:27022
MongoDB shell version: 3.0.6
connecting to: 192.168.221.161:27022
/test
> show dbs
2017-11-14T09:07:45.745-0800 E QUERY Error: listDatabases failed:{
"note"
:
"from execCommand"
,
"ok"
: 0,
"errmsg"
:
"not master"
}
at Error (<anonymous>)
at Mongo.getDBs (src
/mongo/shell/mongo
.js:47:15)
at shellHelper.show (src
/mongo/shell/utils
.js:630:33)
at shellHelper (src
/mongo/shell/utils
.js:524:36)
at (shellhelp2):1:1 at src
/mongo/shell/mongo
.js:47
> db.getMongo().setSlaveOk()
#由于slave节点默认是不可读的,需要先执行这句命令才能查询数据
> show dbs
local
0.078GB
test
0.078GB
> use
test
> db.testdb.
find
()
{
"_id"
: ObjectId(
"5a0b23702c969986fca777ed"
),
"test1"
:
"item1"
}
|
从节点上可以通过命令db.printReplicationInfo()查看服务状态:
1
2
3
4
5
|
> db.printReplicationInfo()
this is a slave, printing slave replication info.
source
: 192.168.221.161:27021
syncedTo: Tue Nov 14 2017 09:12:04 GMT-0800 (PST)
7 secs (0 hrs) behind the freshest member (no primary available at the moment)
|
至此,mongodb的主从架构已经完成了。为防止机器负载过大,也可以配置一主多从服务,master节点只负责写操作,slave节点只提供读操作。
不过,存在几个疑问:
a. 从服务器可以当做主服务器吗,也就是从服务器可写吗?
试一下:
1
2
|
> db.testdb.insert({
"test3"
:
"item3"
})
WriteResult({
"writeError"
: {
"code"
: undefined,
"errmsg"
:
"not master"
} })
|
可以看到,slave节点是不可写的
b.如果master挂掉,从服务器会自动接管主服务,变为可写吗?
把master进程杀掉:
1
|
kill
-9 `
ps
-ef|
grep
mongod|
grep
-
v
grep
|
awk
'{print $2}'
`
|
测试slave节点:
1
2
|
> db.testdb.insert({
"test3"
:
"item3"
})
WriteResult({
"writeError"
: {
"code"
: undefined,
"errmsg"
:
"not master"
} })
|
发现,还是不可写!
这种情况只能手动干预了。。。
继续思考一个问题:
我们怎么实现主节点挂了之后能够自动切换?下一篇接着学习mongodb的集群搭建