Mongodb作为一款非常流行的NOSQL数据库,应用范围非常广泛,它和Nginx-gridfs组合可以构建性能非常出色的应用。下边简单介绍一下如何搭建这套应用。

Mongodb副本集的搭建

在生产环境中,使用单实例的Mongodb显然不能承担重任。Mongodb的副本集是一个mongod进程实例簇,数据在这个簇中相互复制,并且可以自动进行故障切换。这个过程虽然增加了数据冗余,但是确保了高可用性,简化了管理任务。同时,副本集也使分布式存储成为了可能。下面就可是搭建一个简单的副本集:

下载解压Mongodb

最新的稳定版本是3.0.5,将下载下来的安装包解压到指定位置,将解压后的bin文件夹的文件分别复制到/usr/local/Mongorepset/1/、/usr/local/Mongorepset/2/、/usr/local/Mongorepset/3/中,并在这三个文件夹中分别建立data文件夹。

启动mongod初始化副本集

分别在上述三个文件夹中启动mongod,端口号和日志文件分别对应各自的文件夹:

1
2
cd /usr/local/Mongorepset/3
./mongod --dbpath=./data --port=33333 --replSet repset --logpath=./data/1.log --fork

启动mongod之后,启动任意一个mongo,初始化副本集:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
cd /usr/local/Mongorepset/3
./mongo --port=33333

> use admin
switched to db admin
> config={ _id:"repset",members:[
... {_id:0,host:"127.0.0.1:11111"},
... {_id:1,host:"127.0.0.1:22222"},
... {_id:2,host:"127.0.0.1:33333"}]
... }
> rs.initiate(config);

这样,Mongodb副本集就算搭建完成,我们可以看一下现在副本集的状态:

 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
48
49
50
51
repset:SECONDARY> rs.status();
{
	"set" : "repset",
	"date" : ISODate("2015-08-17T12:59:59.910Z"),
	"myState" : 2,
	"members" : [
		{
			"_id" : 0,
			"name" : "127.0.0.1:11111",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 693,
			"optime" : Timestamp(1439816203, 1),
			"optimeDate" : ISODate("2015-08-17T12:56:43Z"),
			"configVersion" : 1,
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "127.0.0.1:22222",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 196,
			"optime" : Timestamp(1439816203, 1),
			"optimeDate" : ISODate("2015-08-17T12:56:43Z"),
			"lastHeartbeat" : ISODate("2015-08-17T12:59:59.561Z"),
			"lastHeartbeatRecv" : ISODate("2015-08-17T12:59:59.561Z"),
			"pingMs" : 0,
			"configVersion" : 1
		},
		{
			"_id" : 2,
			"name" : "127.0.0.1:33333",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 196,
			"optime" : Timestamp(1439816203, 1),
			"optimeDate" : ISODate("2015-08-17T12:56:43Z"),
			"lastHeartbeat" : ISODate("2015-08-17T12:59:59.562Z"),
			"lastHeartbeatRecv" : ISODate("2015-08-17T12:59:59.362Z"),
			"pingMs" : 0,
			"electionTime" : Timestamp(1439816205, 1),
			"electionDate" : ISODate("2015-08-17T12:56:45Z"),
			"configVersion" : 1
		}
	],
	"ok" : 1
}

有一个PRIMARY和两个SECONDARY节点,他们的工作方式如下: ,在应用中,PRIMARY节点负责写入和读取数据,SECONDARY节点负责备份PRIMARY中数据,它们之间通过心跳包来检测彼此的运行状态,如果主节点挂掉,它们在很短的时间内就可以重新推选出一个新的PRIMARY,保证数据库的高可用性。

Nginx-gridfs中副本集的使用

Nginx-gridfs为Nginx提供了直接访问Mongodb的能力,配置Mongodb的副本集也十分简单,只需要在nginx配置文件中对应的location增加字段就可以了:

1
2
3
4
5
6
7
location /gridfs/ {
    gridfs my_app field=filename type=string;
    mongo "repset"
          127.0.0.1:11111
          127.0.0.1:22222
          127.0.0.1:33333;
}

其中Location中的字段gridfs 对应的是数据库名;filed对应的是检索字段,nginx-gridfs提供了对_id和filename的支持;mongo对应的"foo"是副本集的名称;下边则是这个副本集的节点。 保存更新之后的nginx配置文件,重启nginx,就可以愉快地通过Nginx访问Mongodb副本集啦。