5

MongoDB集群部署——Replica Set

 2 years ago
source link: https://www.hi-roy.com/posts/mongodb%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2replica-set/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

MongoDB集群部署——Replica Set

2015-03-03

mongodb的集群部署有3种方式,这里记录我在使用Replica Set(副本集)部署时的步骤。

首先这种方式至少需要3个节点——主、备、仲裁节点。主备节点存储数据,仲裁节点不存储数据,负责决定主节点挂掉之后哪个备节点升级为主节点。客户端同时连接主节点与备节点,不连接仲裁节点。

安装mongodb,CentOS下安装rpmfusion源后使用yum安装即可:yum install mongodb mongodb-server

安装完成后,修改/etc/mongodb.conf 这个配置文件。

bind_ip = 192.168.4.50
port = 27017
fork = true
pidfilepath = /var/run/mongodb/mongodb.pid
logpath = /var/log/mongodb/mongodb.log
dbpath =/var/lib/mongodb
journal = true
directoryperdb=true
logappend=true
replSet=testrs
noprealloc=true

其中注意修改bind_ip为各个节点的IP,下面的4行是我添加的:

  1. directoryperdb:为每一个数据库按照数据库名建立文件夹存放
  2. logappend:以追加的方式记录日志
  3. replSet:replica set的名字
  4. noprealloc:不预先分配存储

修改完成后,使用service mongod start即可启动服务。

随便链接一个节点后,进行配置:

[root@pxc_bj63 ~]# service mongod start
Starting mongod:                                           [  OK  ]
[root@pxc_bj63 ~]# clear
[root@pxc_bj63 ~]# mongo 192.168.4.63:27017
MongoDB shell version: 2.4.12
connecting to: 192.168.4.63:27017/test
> use admin
switched to db admin
> conf = {_id:"testrs",members:[{_id:0,host:"192.168.4.63:27017",priority:2},{_id:1,host:"192.168.4.64:27017",priority:1},{_id:2,host:"192.168.4.50:27017",arbiterOnly:true}]};
{
	"_id" : "testrs",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.4.63:27017",
			"priority" : 2
		},
		{
			"_id" : 1,
			"host" : "192.168.4.64:27017",
			"priority" : 1
		},
		{
			"_id" : 2,
			"host" : "192.168.4.50:27017",
			"arbiterOnly" : true
		}
	]
}

注意最初的_id的值就是我们配置文件中设定的replSet的值,arbiterOnly是大写的O,配置完成后进行初始化:

> rs.initiate(conf)
{
	"info" : "Config now saved locally.  Should come online in about a minute.",
	"ok" : 1
}
> rs.status()
{
	"set" : "testrs",
	"date" : ISODate("2015-03-03T03:17:25Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.4.63:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 460,
			"optime" : Timestamp(1425352584, 1),
			"optimeDate" : ISODate("2015-03-03T03:16:24Z"),
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "192.168.4.64:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 60,
			"optime" : Timestamp(1425352584, 1),
			"optimeDate" : ISODate("2015-03-03T03:16:24Z"),
			"lastHeartbeat" : ISODate("2015-03-03T03:17:25Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:17:25Z"),
			"pingMs" : 0,
			"syncingTo" : "192.168.4.63:27017"
		},
		{
			"_id" : 2,
			"name" : "192.168.4.50:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 58,
			"lastHeartbeat" : ISODate("2015-03-03T03:17:25Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:17:24Z"),
			"pingMs" : 1
		}
	],
	"ok" : 1
}
testrs:PRIMARY>

插入一条数据试试:

testrs:PRIMARY> use test
switched to db test
testrs:PRIMARY> db.testdb.insert({"test1":"i'm master"})

目前,备节点是无法查询数据的:

[root@pxc_bj_64 ~]# mongo 192.168.4.64
MongoDB shell version: 2.4.12
connecting to: 192.168.4.64/test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
	http://docs.mongodb.org/
Questions? Try the support group
	http://groups.google.com/group/mongodb-user
testrs:SECONDARY> use test;
switched to db test
testrs:SECONDARY> show tables;
Tue Mar  3 11:41:00.274 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:128

需要进行配置:

testrs:SECONDARY> db.getMongo().setSlaveOk();
testrs:SECONDARY> db.testdb.find();
{ "_id" : ObjectId("54f52c9073b3842303717165"), "test1" : "i'm master" }

设定setSlaveOK后便可以进行数据查询了。

现在,停止主库的服务,再查看整个集群的状态

testrs:SECONDARY> rs.status();
{
	"set" : "testrs",
	"date" : ISODate("2015-03-03T03:48:40Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.4.63:27017",
			"health" : 0,
			"state" : 8,
			"stateStr" : "(not reachable/healthy)",
			"uptime" : 0,
			"optime" : Timestamp(1425353872, 1),
			"optimeDate" : ISODate("2015-03-03T03:37:52Z"),
			"lastHeartbeat" : ISODate("2015-03-03T03:48:39Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:47:39Z"),
			"pingMs" : 0
		},
		{
			"_id" : 1,
			"name" : "192.168.4.64:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 2317,
			"optime" : Timestamp(1425353872, 1),
			"optimeDate" : ISODate("2015-03-03T03:37:52Z"),
			"self" : true
		},
		{
			"_id" : 2,
			"name" : "192.168.4.50:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 1905,
			"lastHeartbeat" : ISODate("2015-03-03T03:48:39Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:48:40Z"),
			"pingMs" : 1
		}
	],
	"ok" : 1
}

此时原来的备节点变成了主节点,此时我们新插入一条数据:

testrs:PRIMARY> db.testdb.insert({"test2":"i'm new master"})
testrs:PRIMARY> db.testdb.find();
{ "_id" : ObjectId("54f52c9073b3842303717165"), "test1" : "i'm master" }
{ "_id" : ObjectId("54f52f70abb951d25573981e"), "test2" : "i'm new master" }

重启原来的主节点并查看状态:

[root@pxc_bj63 ~]# mongo 192.168.4.63
MongoDB shell version: 2.4.12
connecting to: 192.168.4.63/test
testrs:PRIMARY> rs.status()
{
	"set" : "testrs",
	"date" : ISODate("2015-03-03T03:50:57Z"),
	"myState" : 1,
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.4.63:27017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 59,
			"optime" : Timestamp(1425354608, 1),
			"optimeDate" : ISODate("2015-03-03T03:50:08Z"),
			"self" : true
		},
		{
			"_id" : 1,
			"name" : "192.168.4.64:27017",
			"health" : 1,
			"state" : 2,
			"stateStr" : "SECONDARY",
			"uptime" : 59,
			"optime" : Timestamp(1425354608, 1),
			"optimeDate" : ISODate("2015-03-03T03:50:08Z"),
			"lastHeartbeat" : ISODate("2015-03-03T03:50:56Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:50:57Z"),
			"pingMs" : 0,
			"lastHeartbeatMessage" : "syncing to: 192.168.4.63:27017",
			"syncingTo" : "192.168.4.63:27017"
		},
		{
			"_id" : 2,
			"name" : "192.168.4.50:27017",
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 57,
			"lastHeartbeat" : ISODate("2015-03-03T03:50:56Z"),
			"lastHeartbeatRecv" : ISODate("2015-03-03T03:50:56Z"),
			"pingMs" : 0
		}
	],
	"ok" : 1
}

查询数据也同步过来了:

testrs:PRIMARY> db.testdb.find();
{ "_id" : ObjectId("54f52c9073b3842303717165"), "test1" : "i'm master" }
{ "_id" : ObjectId("54f52f70abb951d25573981e"), "test2" : "i'm new master" }

当主节点恢复后,备节点查询数据时会提示:

testrs:PRIMARY> db.testdb.find();
Tue Mar  3 11:53:00.354 DBClientCursor::init call() failed
Error: error doing query: failed
Tue Mar  3 11:53:00.355 trying reconnect to 192.168.4.64:27017
Tue Mar  3 11:53:00.356 reconnect 192.168.4.64:27017 ok
testrs:SECONDARY>

如果要向集群中新增节点,则进行如下操作:

cfg = rs.conf()
cfg.members[3] = {_id:3,host:"192.168.4.42:27017",priority:0.5}
rs.reconfig(cfg)

新的备份节点配置之前是无法读数据的,记得设定setSlaveOK,不过虽然可读但备份节点还是不可写的。如果想修改配置也同理,首先得到当前配置信息,以修改优先级为例:

cfg = rs.conf()
cfg.members[0].priority = 0.5
cfg.members[1].priority = 2
cfg.members[2].priority = 2
rs.reconfig(cfg)

一定记得reconfig后新配置才会生效。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK