一、概述1、Master-Slave模式(新版已经不推荐):一旦Master停掉,Java客户端就会报异常,这个时候已经没有Master了,Slave不会自动接管Master。2、ReplicaSets:也是一种Master-Slave,但它更健壮,一旦Master停掉后,将会在Slave中选举一个作为Master。
一、概述
1、Master-Slave模式(新版已经不推荐):一旦Master停掉,Java客户端就会报异常,这个时候已经没有Master了,Slave不会自动接管Master。
2、Replica
Sets:也是一种Master-Slave,但它更健壮,一旦Master停掉后,将会在Slave中选举一个作为Master。
二、主从安装
192.168.4.93
192.168.4.94
192.168.4.89
在3台机器上面做主从配置,首先需要在3台机器上面的,相同路径下已经安装好
mongodb(安装在/usr/local/
mongodb/bin/mongod),并且在单机模式下可以正常启动。参考 MongoDB单机安装和使用 。
为了避免不必要的错误,保证3台机器之间能够互相访问,端口不受限制,如果是本地测试机,最好是关掉防火墙(service
iptables stop)。
完成上面的工作外,执行下面操作流程
1、创建主从key文件,用于标识集群的私钥的完整路径,如果各个实例的key file内容不一致,程序将不能正常用。
echo "lifeba secret key" >/data/configs/mongo_rs/key
2、在3台机器上面分别启动实例(先要创建/data/database/mongo_rs,以及/data/logs/日志文件夹)
/usr/local/mongodb/bin/mongod --replSet=rs
--keyFile=/data/configs/mongo_rs/key --fork
--dbpath=/data/database/mongo_rs
--logpath=/data/logs/mongo_rs_log.log --port=27100 --oplogSize 128
--logappend --journal
Replica Sets 配置后启动
提示:
replSet can't get local.system.replset config from self or any seed
(EMPTYCONFIG)
Fri Dec 16 02:44:05 [startReplSets] replSet info you may need to
run replSetInitiate -- rs.initiate() in the shell -- if that is not
already done
这个是因为还没配置rs.initiate(),所以会出现这个提示,等按照下面的配置后就正常了。
3、配置及初始化Replica Sets,只需要在93机器上面操作即可(确认已经关闭防火墙)。
分别执行下面命令
a、./mongo --port=27100
b、use admin
c、cfg={
"_id" : "rs",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "192.168.4.93:27100",
"priority":1
},
{
"_id" : 1,
"host" : "192.168.4.94:27100",
"priority":1
},
{
"_id" : 2,
"host" : "192.168.4.89:27100",
"priority":1
}
]}
d、rs.initiate(cfg)
成功后会提示,其中priority":1 0-1000(含),priority =0 不参与主节点。
{
"info" : "Config now saved locally. Should come online in about a
minute.",
"ok" : 1
}
e、rs.status()
可以看到主从已经配置成功,93机器为PRIMARY,其他两台为SECONDARY,命令行的左边相应有rs1:PRIMARY>
rs1:SECONDARY>标识,要等待一会时间,初始化需要一段时间,如果马上执行该命令,可能看到"errmsg" :
"still initializing" ,"stateStr" : "(not reachable/healthy)"
信息。
{
"set" : "rs",
"date" : ISODate("2012-07-17T07:59:58Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.4.93:27100",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.4.94:27100",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 60,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T07:59:57Z")
},
{
"_id" : 2,
"name" : "192.168.4.89:27100",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 48,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T07:59:58Z")
}
],
"ok" : 1
}
三、其他相关命令
1、rs.isMaster()
查看Replica Sets状态。如果本机是Pri
{
"setName" : "rs",
"ismaster" : true,
"secondary" : false,
"hosts" : [
"192.168.4.93:27100",
"192.168.4.89:27100",
"192.168.4.94:27100"
],
"maxBsonObjectSize" : 16777216,
"ok" : 1
}
2、重新配置config
cOnfig= rs.conf()
{
"_id" : "rs",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "192.168.4.93:27017"
},
{
"_id" : 1,
"host" : "192.168.4.94:27017"
},
{
"_id" : 2,
"host" : "192.168.4.95:27017"
}
]
}
config.version++
config.members[0].priority = 1
config.members[1].priority = 1
config.members[2].priority = 1
rs.reconfig(config)
3、从库可以读,分担压力 ,在从库机子上面执行,否则从库上面读取数据会出现
error: { "$err" : "not master and slaveok=false", "code" : 13435
}
rs:SECONDARY> db.getMongo().setSlaveOk()
4、查看日志
MongoDB的Replica Set
架构是通过一个日志来存储写操作的,这个日志就叫做”oplog”,它存在于”local”数据库中,oplog的大小是可以通过mongod的参数”—oplogSize”来改变oplog的日志大小。
use local
switched to db local
db.oplog.rs.find()
{ "ts" : { "t" : 1342511269000, "i" : 1 }, "h" : NumberLong(0),
"op" : "n", "ns" : "", "o" : { "msg" : "initiating set" } }
字段说明:
ts: 某个操作的时间戳
op: 操作类型,如下:
i: insert
d: delete
u: update
ns: 命名空间,也就是操作的collection name
o: document的内容
db.printReplicationInfo()
configured oplog size: 128MB
log length start to end: 0secs (0hrs)
oplog first event time: Tue Jul 17 2012 15:47:49 GMT+0800 (CST)
oplog last event time: Tue Jul 17 2012 15:47:49 GMT+0800 (CST)
now: Tue Jul 17 2012 16:17:26 GMT+0800 (CST)
字段说明:
configured oplog size: 配置的oplog文件大小
log length start to end: oplog 日志的启用时间段
oplog first event time: 第一个事务日志的产生时间
oplog last event time: 最后一个事务日志的产生时间
now: 现在的时间
5、
use local
db.system.replset.find()
{ "_id" : "rs", "version" : 1, "members" : [
{
"_id" : 0,
"host" : "192.168.4.93:27100"
},
{
"_id" : 1,
"host" : "192.168.4.94:27100"
},
{
"_id" : 2,
"host" : "192.168.4.89:27100"
}
] }
同样可以看到主从配置信息。
6、db.printSlaveReplicationInfo()
source: 192.168.4.94:27100
syncedTo: Tue Jul 17 2012 15:47:49 GMT+0800 (CST)
= 2327secs ago (0.65hrs)
source: 192.168.4.89:27100
syncedTo: Tue Jul 17 2012 15:47:49 GMT+0800 (CST)
= 2327secs ago (0.65hrs)
四、主从读写操作
1、停掉93服务,在94上面执行rs.status(),可以看到89自动成为PRIMARY,重新启动93,则93变为为SECONDARY
{
"set" : "rs",
"date" : ISODate("2012-07-17T00:44:27Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "192.168.4.93:27100",
"health" : 0,
"state" : 1,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T00:44:11Z"),
"errmsg" : "socket exception"
},
{
"_id" : 1,
"name" : "192.168.4.94:27100",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"self" : true
},
{
"_id" : 2,
"name" : "192.168.4.89:27100",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2087,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T00:44:27Z")
}
],
"ok" : 1
}
{
"set" : "rs",
"date" : ISODate("2012-07-17T00:45:27Z"),
"myState" : 2,
"members" : [
{
"_id" : 0,
"name" : "192.168.4.93:27100",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 4,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T00:45:25Z")
},
{
"_id" : 1,
"name" : "192.168.4.94:27100",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"self" : true
},
{
"_id" : 2,
"name" : "192.168.4.89:27100",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2147,
"optime" : {
"t" : 1342511269000,
"i" : 1
},
"optimeDate" : ISODate("2012-07-17T07:47:49Z"),
"lastHeartbeat" : ISODate("2012-07-17T00:45:27Z")
}
],
"ok" : 1
}
2、测试数据主从复制
在93上面执行
uset test
db.a.save({"name":"lifeba.org"})
在94上面
rs:SECONDARY> db.a.find()
error: { "$err" : "not master and slaveok=false", "code" : 13435
}
rs:SECONDARY> db.getMongo().setSlaveOk()
not master and slaveok=false
rs:SECONDARY> db.a.find()
{ "_id" : ObjectId("500524f4dcc7b350450f4c7e"), "name" :
"lifeba.org" }
3、访问下面网址可以看到相应主从配置信息
http://192.168.4.93:28100/_replSet
http://192.168.4.93:28100/
http://192.168.4.93:28100/_status