MongoDB-副本集

副本集就是有自动故障恢复功能的主从集群。主从集群和副本集最为明显的区别就是副本集没有固定的主节点:整个集群会选举出一个主节点,当其不能工作时,则变更到其它节点。副本集总会有一个活跃节点和一个或多个备份节点。
副本集最好的优点就是全自动化的。
standard:常规节点,存储一份完整的数据副本,参与选举投票,可能称为活跃节点。
passive:存储完整的数据副本,参与投票,不能成为活跃节点。
arbiter:仲裁者只负责投票,不接受复制数据,也不能成为活跃节点。

Replica Sets复制(副本集)
在每台MongoDB上执行(三台机器,一主一从一仲裁):

/opt/master/bin/mongod --dbpath /data/master/ --logpath /opt/master/log/mongodb.log --fork --replSet rs1
/opt/slave1/bin/mongod --dbpath /data/slave1/ --logpath /opt/slave1/log/mongodb.log --fork --replSet rs1
/opt/slave2/bin/mongod --dbpath /data/slave2/ --logpath /opt/slave2/log/mongodb.log --fork --replSet rs1
日志会输出:
startup; NoMatchingDocument: Did not find replica set configuration document in local.system.replse
初始化副本(任意一台机器执行):
# /opt/master/bin/mongo #进入MongoDB Shell程序,类似SQL命令行

> use admin; #使用admin数据库
switched to db admin
#定义副本集配置变量,这里的 _id:”repset” 和上面命令参数“ –replSet repset” 要保持一样。 配置:
> config={_id:"rs1",members:[{_id:0,host:"192.168.0.108:27017",priority:2},{_id:1,host:"192.168.0.109:27017",priority:1},{_id:2,host:"192.168.0.113:27017",priority:0,arbiterOnly:true}]}
{
"_id" : "rs1",
"members" : [
{
"_id" : 0,
"host" : "192.168.0.108:27017",
"priority" : 2
},
{
"_id" : 1,
"host" : "192.168.0.109:27017",
"priority" : 1
},
{
"_id" : 2,
"host" : "192.168.0.113:27017",
"priority" : 0,
"arbiterOnly" : true
}
]
}
> rs.initiate(config);
{ "ok" : 1 }
最后应该注意一点,要想使用副本集,从的mongodb的数据必须都是空的,要不然执行 rs.initiate()命令时会提示因存在数据而导致初始化不成功,可以使用 关闭所有副本集,在从节点上执行如下命令,执行完成后启动群集
/opt/slave/bin/mongod --dbpath /data/slave/ --logpath /opt/slave/log/mongodb.log --fork --rest
> show dbs;
admin 0.000GB
local 0.000GB
> use admin;
switched to db admin
> db.dropDatabase();
{ "dropped" : "admin", "ok" : 1 }
> use local;
switched to db local
> db.dropDatabase();
{ "dropped" : "local", "ok" : 1 }
> exit
验证:
rs1:OTHER> rs.status();
{
"set" : "rs1",
"date" : ISODate("2017-04-09T17:31:27.040Z"),
"myState" : 1,
"term" : NumberLong(1),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.0.108:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 300,
"optime" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-04-09T17:31:24Z"),
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1491759084, 1),
"electionDate" : ISODate("2017-04-09T17:31:24Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.0.109:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 13,
"optime" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1491759084, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2017-04-09T17:31:24Z"),
"optimeDurableDate" : ISODate("2017-04-09T17:31:24Z"),
"lastHeartbeat" : ISODate("2017-04-09T17:31:26.336Z"),
"lastHeartbeatRecv" : ISODate("2017-04-09T17:31:25.667Z"),
"pingMs" : NumberLong(0),
"syncingTo" : "192.168.0.108:27017",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.0.113:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 13,
"lastHeartbeat" : ISODate("2017-04-09T17:31:26.336Z"),
"lastHeartbeatRecv" : ISODate("2017-04-09T17:31:25.489Z"),
"pingMs" : NumberLong(1),
"configVersion" : 1
}
],
"ok" : 1
}
rs1:PRIMARY>
"stateStr" : "PRIMARY" #主节点 "stateStr" : "SECONDARY" #从节点 "stateStr" : "ARBITER" #仲裁节点 #查看集群节点的状态 rs.status(); rs.config(); 日志信息:
2017-04-10T01:31:18.737+0800 I REPL [ReplicationExecutor] Member 192.168.0.109:27017 is now in state SECONDARY
2017-04-10T01:31:18.737+0800 I REPL [ReplicationExecutor] Member 192.168.0.113:27017 is now in state ARBITER
在主节点插入数据测试:
rs1:PRIMARY> use wgl
switched to db wgl
rs1:PRIMARY> db.wgl.insert({"1":"1"})
WriteResult({ "nInserted" : 1 })
rs1:PRIMARY> db.wgl.find()
{ "_id" : ObjectId("58eb5bce63e260f6cd98a84d"), "1" : "1" }
测试从节点可读不:
rs1:SECONDARY> use wgl;
switched to db wgl
rs1:SECONDARY> db.wgl.find();
{ "_id" : ObjectId("58eb5bce63e260f6cd98a84d"), "1" : "1" }
rs1:SECONDARY> db.wgl.insert({"2":"2"})
WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } })
rs1:SECONDARY> db.wgl.find();
{ "_id" : ObjectId("58eb5bce63e260f6cd98a84d"), "1" : "1" }
rs1:SECONDARY> show tables
wgl

rs1:SECONDARY> show tabels;
2017-04-10T01:41:30.048+0800 E QUERY [thread1] Error: don't know how to show [tabels] :
shellHelper.show@src/mongo/shell/utils.js:898:11
shellHelper@src/mongo/shell/utils.js:651:15
@(shellhelp2):1:1

rs1:SECONDARY> db.getMongo().setSlaveOk();
rs1:SECONDARY> db.test.find();
{ "_id" : ObjectId("58ea71fd2836cb8795c0d42c"), "1" : "1" }
关闭主节点
/opt/master/bin/mongod --dbpath /data/master/ --shutdown #主节点执行
REPL [ReplicationExecutor] transition to PRIMARY #从节点日志反馈
[rsSync] transition to primary complete; database writes are now permitted #从日志写入开始
#从节点登陆
/opt/master/bin/mongo
rs1:PRIMARY> #变成主了
rs1:PRIMARY> rs.status();
{
"set" : "rs1",
"date" : ISODate("2017-04-09T17:50:59.116Z"),
"myState" : 1,
"term" : NumberLong(2),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1491759965, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1491760251, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1491760251, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.0.108:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2017-04-09T17:50:57.640Z"),
"lastHeartbeatRecv" : ISODate("2017-04-09T17:46:11.614Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "192.168.0.109:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1465,
"optime" : {
"ts" : Timestamp(1491760251, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2017-04-09T17:50:51Z"),
"electionTime" : Timestamp(1491759981, 1),
"electionDate" : ISODate("2017-04-09T17:46:21Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 2,
"name" : "192.168.0.113:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1183,
"lastHeartbeat" : ISODate("2017-04-09T17:50:57.369Z"),
"lastHeartbeatRecv" : ISODate("2017-04-09T17:50:56.223Z"),
"pingMs" : NumberLong(0),
"configVersion" : 1
}
],
"ok" : 1
}
三台机器主从状态分别如下: "stateStr" : "(not reachable/healthy)", "stateStr" : "PRIMARY", "stateStr" : "ARBITER", 查看群集IP信息:
rs1:PRIMARY> rs.isMaster();
{
"hosts" : [
"192.168.1.119:27017",
"192.168.1.151:27017"
],
"arbiters" : [
"192.168.1.251:27017"
],
"setName" : "rs1",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.1.119:27017",
"me" : "192.168.1.119:27017",
"electionId" : ObjectId("7fffffff0000000000000006"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1491820361, 1),
"t" : NumberLong(6)
},
"lastWriteDate" : ISODate("2017-04-10T10:32:41Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2017-04-10T10:32:44.800Z"),
"maxWireVersion" : 5,
"minWireVersion" : 0,
"readOnly" : false,
"ok" : 1
}
恢复原先主节点: 查看主节点的日志发现
I REPL [ReplicationExecutor] Member 192.168.1.251:27017 is now in state ARBITER
I REPL [ReplicationExecutor] Member 192.168.1.151:27017 is now in state PRIMARY
发现原先主节点抢回了主节点地位,拥有占先权! 通过rs.add(‘ip:port’)增加节点
rs1:PRIMARY> rs.add('192.168.1.151:27018')
{ "ok" : 1 }

rs1:PRIMARY> rs.status();
{
"set" : "rs1",
"date" : ISODate("2017-04-10T10:35:01.220Z"),
"myState" : 1,
"term" : NumberLong(6),
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"appliedOpTime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"durableOpTime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.1.119:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 641,
"optime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2017-04-10T10:34:58Z"),
"electionTime" : Timestamp(1491819871, 2),
"electionDate" : ISODate("2017-04-10T10:24:31Z"),
"configVersion" : 2,
"self" : true
},
{
"_id" : 1,
"name" : "192.168.1.151:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 640,
"optime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"optimeDurable" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2017-04-10T10:34:58Z"),
"optimeDurableDate" : ISODate("2017-04-10T10:34:58Z"),
"lastHeartbeat" : ISODate("2017-04-10T10:35:00.594Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:34:58.645Z"),
"pingMs" : NumberLong(4),
"configVersion" : 2
},
{
"_id" : 2,
"name" : "192.168.1.251:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 640,
"lastHeartbeat" : ISODate("2017-04-10T10:35:00.564Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:34:58.573Z"),
"pingMs" : NumberLong(0),
"configVersion" : 2
},
{
"_id" : 3,
"name" : "192.168.1.151:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2,
"optime" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"optimeDurable" : {
"ts" : Timestamp(1491820498, 1),
"t" : NumberLong(6)
},
"optimeDate" : ISODate("2017-04-10T10:34:58Z"),
"optimeDurableDate" : ISODate("2017-04-10T10:34:58Z"),
"lastHeartbeat" : ISODate("2017-04-10T10:35:00.564Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:34:59.308Z"),
"pingMs" : NumberLong(1),
"configVersion" : 2
}
],
"ok" : 1
}
移除节点用 rs.remove(“ip:port”); 再次查看集群状态发现节点被移除了
rs1:PRIMARY> rs.remove('192.168.1.151:27018')
{ "ok" : 1 }
停掉主节点:
192.168.1.151:27018变成主了
rs1:SECONDARY> rs.status();
{
"set" : "rs1",
"date" : ISODate("2017-04-10T10:38:44.358Z"),
"myState" : 2,
"term" : NumberLong(7),
"syncingTo" : "192.168.1.151:27018",
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1491820691, 1),
"t" : NumberLong(6)
},
"appliedOpTime" : {
"ts" : Timestamp(1491820722, 1),
"t" : NumberLong(7)
},
"durableOpTime" : {
"ts" : Timestamp(1491820722, 1),
"t" : NumberLong(7)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.1.119:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2017-04-10T10:38:44.238Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:38:11.731Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Connection refused",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "192.168.1.151:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1388,
"optime" : {
"ts" : Timestamp(1491820722, 1),
"t" : NumberLong(7)
},
"optimeDate" : ISODate("2017-04-10T10:38:42Z"),
"syncingTo" : "192.168.1.151:27018",
"configVersion" : 4,
"self" : true
},
{
"_id" : 2,
"name" : "192.168.1.251:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 1304,
"lastHeartbeat" : ISODate("2017-04-10T10:38:44.214Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:38:43.288Z"),
"pingMs" : NumberLong(1),
"configVersion" : 4
},
{
"_id" : 3,
"name" : "192.168.1.151:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 96,
"optime" : {
"ts" : Timestamp(1491820722, 1),
"t" : NumberLong(7)
},
"optimeDurable" : {
"ts" : Timestamp(1491820722, 1),
"t" : NumberLong(7)
},
"optimeDate" : ISODate("2017-04-10T10:38:42Z"),
"optimeDurableDate" : ISODate("2017-04-10T10:38:42Z"),
"lastHeartbeat" : ISODate("2017-04-10T10:38:44.213Z"),
"lastHeartbeatRecv" : ISODate("2017-04-10T10:38:43.986Z"),
"pingMs" : NumberLong(0),
"electionTime" : Timestamp(1491820701, 1),
"electionDate" : ISODate("2017-04-10T10:38:21Z"),
"configVersion" : 4
}
],
"ok" : 1
}
-------------本文结束感谢您的阅读-------------