MongoDB副本集
MongoDB提供两种复制风格:主从复制、副本集
- 两种方式都是在一个主节点进行写操作(写入的数据被异步地同步到所有的从节点),并从节点上读取数据。
- 副本集保证自动故障转移,如果主节点由于某种原因下线,可能的花,会自动将一哥从节点提升为主节点。
- 只有一种情况需要选择MongoDB的主从复制,即需要超过11个从节点时,因为副本集不能包含12个以上的成员。
为副本集的每个成员创建数据目录:
[root@vhost2 ~]# mkdir -p /data/mongo1
[root@vhost2 ~]# mkdir -p /data/mongo2
[root@vhost2 ~]# mkdir -p /data/mongo3
启动mongod
[root@vhost2 ~]# mongod --replSet myapp --dbpath /data/mongo1 --port 40001 &
[root@vhost2 ~]# mongod --replSet myapp --dbpath /data/mongo2 --port 40002 &
[root@vhost2 ~]# mongod --replSet myapp --dbpath /data/mongo3 --port 40003 &
配置副本集,先连接到一个刚启动的非冲裁节点的mongod上,
[root@vhost2 ~]# mongo 127.0.0.1:40001/admin
MongoDB Enterprise > rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "vhost2:40001",
"ok" : 1
}
MongoDB Enterprise myapp:OTHER>
1分钟之后,配置了拥有一个单成员的副本集,通过rs.add()添加其他两个成员:
MongoDB Enterprise myapp:PRIMARY> rs.add("vhost2:40002")
{ "ok" : 1 }
MongoDB Enterprise myapp:PRIMARY> rs.add("vhost2.local:40003",{arbiterOnly:true})
{ "ok" : 1 }
#arbiterOnly,创建仲裁节点,1分钟之后,所有成员都在线
db.isMaster():获取副本集状态的摘要信息
MongoDB Enterprise myapp:PRIMARY> db.isMaster()
{ "hosts" : [ "vhost2:40001", "vhost2:40002" ], "arbiters" : [ "vhost2:40003" ], "setName" : "myapp", "setVersion" : 5, "ismaster" : true, "secondary" : false, "primary" : "vhost2:40001", "me" : "vhost2:40001", "electionId" : ObjectId("7fffffff0000000000000001"), "lastWrite" : { "opTime" : { "ts" : Timestamp(1512824958, 1), "t" : NumberLong(1) }, "lastWriteDate" : ISODate("2017-12-09T13:09:18Z") }, "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-12-09T13:09:24.062Z"), "maxWireVersion" : 5, "minWireVersion" : 0, "readOnly" : false, "ok" : 1 }
#rs.status()提供详细的系统信息,除非MongoDB数据库中包含数据量比较大,否则副本集能在30s内上线,在此期间,每个节点的
statStr字段应该会从RECOVERING变为PRIMARY,SECONDARY或ARBITER。
rs.status() 查看副本集主从节点的状态
MongoDB Enterprise myapp:PRIMARY> rs.status()
{ "set" : "myapp", "date" : ISODate("2017-12-09T13:08:41.030Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "vhost2:40001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 4026, "optime" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-09T13:08:38Z"), "electionTime" : Timestamp(1512820966, 2), "electionDate" : ISODate("2017-12-09T12:02:46Z"), "configVersion" : 5, "self" : true }, { "_id" : 1, "name" : "vhost2:40002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 3501, "optime" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512824918, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-09T13:08:38Z"), "optimeDurableDate" : ISODate("2017-12-09T13:08:38Z"), "lastHeartbeat" : ISODate("2017-12-09T13:08:39.445Z"), "lastHeartbeatRecv" : ISODate("2017-12-09T13:08:40.483Z"), "pingMs" : NumberLong(0), "syncingTo" : "vhost2:40001", "configVersion" : 5 }, { "_id" : 2, "name" : "vhost2:40003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 2942, "lastHeartbeat" : ISODate("2017-12-09T13:08:40.900Z"), "lastHeartbeatRecv" : ISODate("2017-12-09T13:08:39.725Z"), "pingMs" : NumberLong(0), "configVersion" : 5 } ], "ok" : 1 }
"health" : 1, #1 表明正常; 0 表明异常
"state" : 1, # 1 表明是Primary; 2 表明是Secondary;
"stateStr" : "PRIMARY", #表明此机器是主库
MongoDB Enterprise myapp:PRIMARY>
主节点插入数据
[root@vhost2 ~]# mongo vhost2:40001/admin
MongoDB Enterprise myapp:PRIMARY> use bookstore;
switched to db bookstore
MongoDB Enterprise myapp:PRIMARY> db.books.insert({title:"Oliver Twist"})
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise myapp:PRIMARY> show dbs;
admin 0.000GB
bookstore 0.000GB
local 0.000GB
MongoDB Enterprise myapp:PRIMARY> db.books.find()
{ "_id" : ObjectId("5a2be17a65e2395a10373f77"), "title" : "Oliver Twist" }
从节点:
[root@vhost2 ~]# mongo vhost2:40002
MongoDB Enterprise myapp:SECONDARY> show dbs;
2017-12-09T08:16:59.482-0500 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:781:19
shellHelper@src/mongo/shell/utils.js:671:15
@(shellhelp2):1:1
MongoDB Enterprise myapp:SECONDARY>
SECONDARY是不允许读写的,如果非要解决,方法如下:
rs.slaveOk();
MongoDB Enterprise myapp:SECONDARY> rs.slaveOk();
MongoDB Enterprise myapp:SECONDARY> show dbs;
admin 0.000GB
bookstore 0.000GB
local 0.000GB
MongoDB Enterprise myapp:SECONDARY> use bookstore
switched to db bookstore
MongoDB Enterprise myapp:SECONDARY> db.books.find()
{ "_id" : ObjectId("5a2be17a65e2395a10373f77"), "title" : "Oliver Twist" }
冲裁节点:
[root@vhost2 ~]# mongo vhost2:40003
MongoDB Enterprise myapp:ARBITER> rs.slaveOk();
MongoDB Enterprise myapp:ARBITER> show dbs;
local 0.000GB
切换:关闭主节点,CTRL-C、kill -2 或在SHELL中运行db.shutdownServer()
[root@vhost2 ~]# kill -2 26036
[root@vhost2 ~]# mongo vhost2:40002
MongoDB Enterprise myapp:PRIMARY> show dbs;
admin 0.000GB
bookstore 0.000GB
local 0.000GB
MongoDB Enterprise myapp:PRIMARY> rs.status()
{ "set" : "myapp", "date" : ISODate("2017-12-09T14:22:06.153Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1512829209, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1512829322, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1512829322, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "vhost2:40001", "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-12-09T14:22:04.668Z"), "lastHeartbeatRecv" : ISODate("2017-12-09T14:20:08.573Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "vhost2:40002", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 8409, "optime" : { "ts" : Timestamp(1512829322, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-12-09T14:22:02Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1512829220, 1), "electionDate" : ISODate("2017-12-09T14:20:20Z"), "configVersion" : 5, "self" : true }, { "_id" : 2, "name" : "vhost2:40003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 7304, "lastHeartbeat" : ISODate("2017-12-09T14:22:04.428Z"), "lastHeartbeatRecv" : ISODate("2017-12-09T14:22:05.986Z"), "pingMs" : NumberLong(0), "configVersion" : 5 } ], "ok" : 1 } MongoDB Enterprise myapp:PRIMARY>
故障转移后,副本集就只有两个节点,仲裁节点没有数据。假设旧的主节点正常关闭,启动该节点,
它将以从节点的身份重新键入副本集:
重启主节点:
[root@vhost2 ~]# mongo vhost2:40001/admin
MongoDB Enterprise myapp:SECONDARY> show dbs;
2017-12-09T09:24:34.262-0500 E QUERY [thread1] Error: listDatabases failed:{
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:781:19
shellHelper@src/mongo/shell/utils.js:671:15
@(shellhelp2):1:1
MongoDB Enterprise myapp:SECONDARY> rs.slaveOk()
MongoDB Enterprise myapp:SECONDARY> show dbs;
admin 0.000GB
bookstore 0.000GB
local 0.000GB
MongoDB Enterprise myapp:SECONDARY> rs.st
rs.status( rs.stepDown(
MongoDB Enterprise myapp:SECONDARY> rs.status()
{
"set" : "myapp",
"date" : ISODate("2017-12-09T14:24:47.063Z"),
"myState" : 2,
"term" : NumberLong(2),
"syncingTo" : "vhost2:40002",
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
}
},
"members" : [
{
"_id" : 0,
"name" : "vhost2:40001",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 77,
"optime" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2017-12-09T14:24:42Z"),
"syncingTo" : "vhost2:40002",
"configVersion" : 5,
"self" : true
},
{
"_id" : 1,
"name" : "vhost2:40002",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 63,
"optime" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1512829482, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2017-12-09T14:24:42Z"),
"optimeDurableDate" : ISODate("2017-12-09T14:24:42Z"),
"lastHeartbeat" : ISODate("2017-12-09T14:24:45.594Z"),
"lastHeartbeatRecv" : ISODate("2017-12-09T14:24:47.010Z"),
"pingMs" : NumberLong(0),
"electionTime" : Timestamp(1512829220, 1),
"electionDate" : ISODate("2017-12-09T14:20:20Z"),
"configVersion" : 5
},
{
"_id" : 2,
"name" : "vhost2:40003",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 63,
"lastHeartbeat" : ISODate("2017-12-09T14:24:45.598Z"),
"lastHeartbeatRecv" : ISODate("2017-12-09T14:24:46.216Z"),
"pingMs" : NumberLong(0),
"configVersion" : 5
}
],
"ok" : 1
}
MongoDB Enterprise myapp:SECONDARY>
https://www.cnblogs.com/wadeyu/p/7930608.html