为什么80%的码农都做不了架构师?>>>
一、环境
$ cat /etc/redhat-release
CentOS Linux release 7.0.1406 (Core)
$ uname -a
Linux zhaopin-2-201 3.10.0-123.el7.x86_64 #1 SMP Mon Jun 30 12:09:22 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ mongo --version
MongoDB shell version: 3.0.6
二、准备
1.创建目录
$ sudo mkdir -p /data/mongodb/{data/db0,backup/db0,log/db0,conf/db0}
2.编写配置文件
$ sudo vim /data/mongodb/conf/db0/mongodb.conf
# base
port = 27017
maxConns = 800
filePermissions = 0700
fork = true
noauth = true
directoryperdb = true
dbpath = /data/mongodb/data/db0
pidfilepath = /data/mongodb/data/db0/mongodb.pid
journal = true
# security
nohttpinterface = true
rest = false
# log
logpath = /data/mongodb/log/db0/mongodb.log
logRotate = rename
logappend = true
slowms = 50
replSet = rs0
三、配置副本集
1.配置primary
1)启动
$ sudo /opt/mongodb/bin/mongod --config /data/mongodb/conf/db0/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 48583
child process started successfully, parent exiting
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> rs.status();
{
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94
}
2)初始化
> cfg={_id:"rs0", members:[ {_id:0,host:"172.30.2.201:27017"}] }
{
"_id" : "rs0",
"members" : [
{
"_id" : 0,
"host" : "172.30.2.201:27017"
}
]
}
> rs.initiate( cfg );
{ "ok" : 1 }
rs0:OTHER> rs.status();
{
"set" : "rs0",
"date" : ISODate("2015-09-25T08:31:36.354Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.30.2.201:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 112,
"optime" : Timestamp(1443169891, 1),
"optimeDate" : ISODate("2015-09-25T08:31:31Z"),
"electionTime" : Timestamp(1443169891, 2),
"electionDate" : ISODate("2015-09-25T08:31:31Z"),
"configVersion" : 1,
"self" : true
}
],
"ok" : 1
}
2.添加节点
1)启动新的节点
$ sudo /opt/mongodb/bin/mongod --config /data/mongodb/conf/db0/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 41794
child process started successfully, parent exiting
$ sudo /opt/mongodb/bin/mongod --config /data/mongodb/conf/db0/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 3761
child process started successfully, parent exiting
2)添加新的节点
在primary上执行:
rs0:PRIMARY> rs.add( "172.30.2.202:27017" );
{ "ok" : 1 }
rs0:PRIMARY> rs.status();
{
"set" : "rs0",
"date" : ISODate("2015-09-25T08:34:48.161Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.30.2.201:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 304,
"optime" : Timestamp(1443170060, 1),
"optimeDate" : ISODate("2015-09-25T08:34:20Z"),
"electionTime" : Timestamp(1443169891, 2),
"electionDate" : ISODate("2015-09-25T08:31:31Z"),
"configVersion" : 2,
"self" : true
},
{
"_id" : 1,
"name" : "172.30.2.202:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 27,
"optime" : Timestamp(1443170060, 1),
"optimeDate" : ISODate("2015-09-25T08:34:20Z"),
"lastHeartbeat" : ISODate("2015-09-25T08:34:46.884Z"),
"lastHeartbeatRecv" : ISODate("2015-09-25T08:34:46.896Z"),
"pingMs" : 0,
"configVersion" : 2
}
],
"ok" : 1
}
rs0:PRIMARY> rs.add( "172.30.2.203:27017" );
{ "ok" : 1 }
rs0:PRIMARY> rs.status();
{
"set" : "rs0",
"date" : ISODate("2015-09-25T08:36:22.579Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.30.2.201:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 398,
"optime" : Timestamp(1443170158, 1),
"optimeDate" : ISODate("2015-09-25T08:35:58Z"),
"electionTime" : Timestamp(1443169891, 2),
"electionDate" : ISODate("2015-09-25T08:31:31Z"),
"configVersion" : 3,
"self" : true
},
{
"_id" : 1,
"name" : "172.30.2.202:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 121,
"optime" : Timestamp(1443170158, 1),
"optimeDate" : ISODate("2015-09-25T08:35:58Z"),
"lastHeartbeat" : ISODate("2015-09-25T08:36:22.268Z"),
"lastHeartbeatRecv" : ISODate("2015-09-25T08:36:20.949Z"),
"pingMs" : 0,
"syncingTo" : "172.30.2.201:27017",
"configVersion" : 3
},
{
"_id" : 2,
"name" : "172.30.2.203:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 24,
"optime" : Timestamp(1443170158, 1),
"optimeDate" : ISODate("2015-09-25T08:35:58Z"),
"lastHeartbeat" : ISODate("2015-09-25T08:36:22.267Z"),
"lastHeartbeatRecv" : ISODate("2015-09-25T08:36:22.275Z"),
"pingMs" : 0,
"configVersion" : 3
}
],
"ok" : 1
}
3. 设置开机启动
$ sudo vim /etc/rc.local
/opt/mongodb/bin/mongod --config /data/mongodb/conf/db0/mongodb.conf
四、验证
1.数据同步
1) primary:
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
rs0:PRIMARY> use aaa;
switched to db aaa
rs0:PRIMARY> db.createCollection( "test" );
{ "ok" : 1 }
rs0:PRIMARY> show collections;
system.indexes
test
2) secondary:
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
rs0:SECONDARY> rs.slaveOk();
rs0:SECONDARY> use aaa;
switched to db aaa
rs0:SECONDARY> show collections;
system.indexes
test
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
rs0:SECONDARY> rs.slaveOk();
rs0:SECONDARY> use aaa;
switched to db aaa
rs0:SECONDARY> show collections;
system.indexes
test
2.读写验证
由上可知,primary是可读写的
在secondary上写测试:
$ mongo
MongoDB shell version: 3.0.6
connecting to: test
> use aaa;
switched to db aaa
> db.createCollection("test2");
{ "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
> show collections;
2015-09-23T15:57:49.240+0800 E QUERY Error: listCollections failed: { "note" : "from execCommand", "ok" : 0, "errmsg" : "not master" }
at Error (<anonymous>)
at DB._getCollectionInfosCommand (src/mongo/shell/db.js:646:15)
at DB.getCollectionInfos (src/mongo/shell/db.js:658:20)
at DB.getCollectionNames (src/mongo/shell/db.js:669:17)
at shellHelper.show (src/mongo/shell/utils.js:625:12)
at shellHelper (src/mongo/shell/utils.js:524:36)
at (shellhelp2):1:1 at src/mongo/shell/db.js:646
> rs.slaveOk();
> show collections;
system.indexes
test
>
证明secondary节点是不能写,默认也是不可读的,需要执行rs.slaveOk();或者db.getMongo().setSlaveOk();并且只对当前session有效,所以每次连接从库都需要执行。
五、说明
mongodb的副本集至少需要3台以上才能实现高可用,并且节点的个数最好是基数。