Mongodb之前一直是做主从模式,后来官方推荐用Replica Set(简称RS)来代替主从,主要是当primary节点出现故障后,RS集群内会有自动投票选举primary节点的机制,自动选出新的primary节点,这样应用程序就不需要关心主从切换的问题。想要配置一个简单的RS,至少要两台机器。我本地用了VMware以NAT方式跑了两台VPS,IP分别是:192.168.33.112和192.168.33.119,注意两台VPS的访问互通问题(iptables network等)


1.ssh登陆到112那台机器上,先下载mongodb最新版 现在是3.0.5 (3.x版本彪悍了很多,无论从读写的性能,还是数据压缩能力)

cd /usr/local/bin
wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.5.tgz
tar -zxvf  mongodb-linux-x86_64-3.0.5.tar
mv mongodb-linux-x86_64-3.0.5/ mongodb



2.建立mongodb需要的一些必要的文件夹

mkdir -p /mnt/mongodb/rs/data
mkdir -p /mnt/mongodb/rs/logs
mkdir -p /mnt/mongodb/rs/config



3.创建配置文件

vi /mnt/mongodb/rs/config/mongod.conf



insert以下内容:

dbpath=/mnt/mongodb/rs/data   #数据存放目录
logpath=/mnt/mongodb/rs/logs/mongod.log  #日志文件目录
pidfilepath=/mnt/mongodb/rs/mongod.pid  #pid端口文件

port=27017   #mongodb端口

logappend=true   #追加方式写日志文件
fork=true        #后台运行
journal=true     #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里
oplogSize=2048   #同步操作记录文件大小(MB)
smallfiles=true  #使用较小的默认文件

replSet=27017_0    #副本集名称,同一个副本集,名称必须一致

4.跑mongod进程

cd /usr/local/bin/mongodb/bin/
./mongod -f /mnt/mongodb/rs/config/mongod.conf



启动成功的时候终端会提示

about to fork child process, waiting until server is ready for connections.
forked process: 1286
child process started successfully, parent exiting

然后以同样的方式在119那台机也让mongod跑起来...



5.随便一台机器进入命令行管理mongodb,启动RS:

./mongo 127.0.0.1:27017/admin



输入RS配置命令

config={_id : '27017_0',members : [{_id : 1, host : '192.168.33.119:27017'},{_id : 2, host : '192.168.33.112:27017'}]}



系统会自动格式化显示出:

{
	"_id" : "27017_0",
	"members" : [
		{
			"_id" : 1,
			"host" : "192.168.33.119:27017"
		},
		{
			"_id" : 2,
			"host" : "192.168.33.112:27017"
		}
	]
}



这里我们让112和119来做RS集群,然后接下来初始化集群:

rs.initiate(config);



系统会提示:{ "ok" : 1 } 证明启动成功!

再输入命令检查RS状态:

rs.status()



系统会显示:

{
	"set" : "27017_0",
	"date" : ISODate("2015-08-24T19:41:37.778Z"),
	"myState" : 2,
	"members" : [
		{
			"_id" : 1,
			"name" : "192.168.33.119:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 14,
			"optime" : Timestamp(1440445283, 1),
			"optimeDate" : ISODate("2015-08-24T19:41:23Z"),
			"lastHeartbeat" : ISODate("2015-08-24T19:41:37.226Z"),
			"lastHeartbeatRecv" : ISODate("2015-08-24T19:41:37.238Z"),
			"pingMs" : 1,
			"electionTime" : Timestamp(1440445283, 2),
			"electionDate" : ISODate("2015-08-24T19:41:23Z"),
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "192.168.33.112:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 129,
			"optime" : Timestamp(1440445283, 1),
			"optimeDate" : ISODate("2015-08-24T19:41:23Z"),
			"configVersion" : 1,
			"self" : true
		}
	],
	"ok" : 1
}



这里我们可以看到RS集群的详细信息,可以看到119那台机器被选为primary节点,112被选为secondary节点,以后如果要添加机器做横向扩展的时候 只需要将要添加到集群中的机器add进来就行了,或者某台机器出了故障需要排除的话,也可以很方便的remove掉。


6.使用PHP来连接:

对于应用端(PHP),在框架连接mongodb的类里面,你可以这样写:

$m = new MongoClient("mongodb://192.168.33.112:27017,192.168.33.119:27017", array("replicaSet" => "27017_0"));
$data = array('act_id'=>345, 'act_code'=>'freebeauty');
$res = $m->testdb->testcollection->insert($data);

注意replicaset(副本集名)要写上,这样集群才可以自动发现节点...

然后在主节点命令行下(默认slave节点没法读写):

27017_0:PRIMARY> use testdb;
switched to db testdb
27017_0:PRIMARY> db.testcollection.find();
{ "_id" : ObjectId("55dbe8c83643a783470041a7"), "act_id" : NumberLong(345), "act_code" : "freebeauty" }
27017_0:PRIMARY>

写入成功验证!

如果你在secondary节点访问的话,是不可读的:

27017_0:SECONDARY> db.testcollection.find();
Error: error: { "$err" : "not master and slaveOk=false", "code" : 13435 }
27017_0:SECONDARY> 
27017_0:SECONDARY>



That's it~