接上文,我们已经搭建成功了,下面是我们查看日志等详细解读
我们可以通过执行“db.printCollectionStats()”命令查看到操作日志的一些基本信息,如大小,日志启动时间等,查看primary 的oplog.rs表的元信息,代码如下:
PRIMARY> db.printCollectionStats()
oplog.rs { "ns" : "local.oplog.rs", "count" : 1, "size" : 80, "avgObjSize" : 80, "storageSize" : 990003200, "numExtents" : 1, "nindexes" : 0, "lastExtentSize" : 990003200, "paddingFactor" : 1, "flags" : 0, "totalIndexSize" : 0, "indexSizes" : { }, "capped" : 1, "max" : 2147483647, "ok" : 1 } --- system.replset { "ns" : "local.system.replset", "count" : 1, "size" : 176, "avgObjSize" : 176, "storageSize" : 12288, "numExtents" : 1, "nindexes" : 0, "lastExtentSize" : 12288, "paddingFactor" : 1, "flags" : 0, "totalIndexSize" : 0, "indexSizes" : { }, "ok" : 1 } --- PRIMARY>复制集搭建之后,需要做的第一件事就是要查看复制集的同步状态,因为如果复制集数据不同步,mongodb的复制集是不会起到任何效果的,通过执行“db.printSlaveReplicationInfo()”命令,查看所有slave延时情况,例如:28011,28012端口上的slave的同步状态。代码如下:
PRIMARY> db.printSlaveReplicationInfo()
source: localhost:28011 syncedTo: Fri Jul 25 2014 10:03:17 GMT+0800 (CST) = 3437 secs ago (0.95hrs) source: localhost:28012 syncedTo: Fri Jul 25 2014 10:03:17 GMT+0800 (CST) = 3437 secs ago (0.95hrs) PRIMARY>字段说明:
1, source :从库的IP及端口
2,syncedTo: 目前的同步情况,以及最后一次同步时间等信息。
主从配置信息
PRIMARY> db
local PRIMARY> show collections oplog.rs system.replset PRIMARY> db.system.replset.find() { "_id" : "rs1", "version" : 1, "members" : [{ "_id" : 0, "host" : "localhost:28010" },
{ "_id" : 1, "host" : "localhost:28011" },
{ "_id" : 2, "host" : "localhost:28012" } ]
}
PRIMARY>在本例中,字段ID存储复制集的名字,本例中的值是rs1,字段“members”存储复制集成员的IP及端口信息。
管理Replica Sets
1,主从切换
mongodb复制集测试环境
端口 当前成员角色 目标成员角色
28010 主 从
28011 从 从
28012 从 主
在本例中,端口28010对应的是主库,现在要将主库放到28012的端口上,下面逐步引导大家完成配置
步骤1:除了现有的主实例(端口28010)和目标主实例(端口28012)以外,其他的实例群全部设置为“冰冻”(freeze)状态,即(非主状态);
本实例中将端口28011“冰冻”,代码如下
PRIMARY> exit --------------退出,切换到我们的27011
bye [root@dota ~]# /usr/local/mongodb/bin/mongo --port 28011 MongoDB shell version: 2.0.4 connecting to: 127.0.0.1:28011/test SECONDARY> rs.freeze(30) { "ok" : 1 } SECONDARY>通过执行“rs.freeze(30)”命令,将端口在28011上的实例“冰冻”,其中30的单位是秒,说明30秒内这个实例不会参与primary的内部选举工作,即30内此实例不会变成primary角色,那么就充分利用三十秒的时间完成切换工作。
步骤2,将当前主库的实例降级,
将端口在28010的主库实例降级,代码如下:
[root@dota ~]# /usr/local/mongodb/bin/mongo --port 28010
MongoDB shell version: 2.0.4 connecting to: 127.0.0.1:28010/test PRIMARY> rs.stepDown() Fri Jul 25 11:25:20 DBClientCursor::init call() failed Fri Jul 25 11:25:20 query failed : admin.$cmd { replSetStepDown: 60.0 } to: 127.0.0.1:28010 Fri Jul 25 11:25:20 Error: error doing query: failed shell/collection.js:151 Fri Jul 25 11:25:20 trying reconnect to 127.0.0.1:28010 Fri Jul 25 11:25:20 reconnect 127.0.0.1:28010 ok
步骤3,查看操作之后的状态
通过rs.status()查看操作后的状态
SECONDARY> rs.status()
{ "set" : "rs1", "date" : ISODate("2014-07-25T03:29:03Z"), "myState" : 2, "syncingTo" : "localhost:28012", "members" : [ { "_id" : 0, "name" : "localhost:28010", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", -------此处降级实现 "optime" : { "t" : 1406253797000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T02:03:17Z"), "self" : true }, { "_id" : 1, "name" : "localhost:28011", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 219, "optime" : { "t" : 1406253797000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T02:03:17Z"), "lastHeartbeat" : ISODate("2014-07-25T03:29:02Z"), "pingMs" : 0 }, { "_id" : 2, "name" : "localhost:28012", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", -----看看,这货升级了 "uptime" : 219, "optime" : { "t" : 1406253797000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T02:03:17Z"), "lastHeartbeat" : ISODate("2014-07-25T03:29:02Z"), "pingMs" : 0 } ], "ok" : 1 } SECONDARY>
读写分离
步骤一:先向主库插入一条测试数据,代码如下
------我们前面做了主从切换,28010不是 主,28012才是主,搞清楚实验环境
[root@dota ~]# /usr/local/mongodb/bin/mongo --port 28012
MongoDB shell version: 2.0.4 connecting to: 127.0.0.1:28012/test PRIMARY> db test PRIMARY> db.c1.insert({age:30}) PRIMARY> db.c1.find() { "_id" : ObjectId("53d1ed7cb017538f84368f95"), "age" : 30 }
步骤二:在从库中执行查询操作,代码如下
------切换到从库
[root@dota ~]# /usr/local/mongodb/bin/mongo --port 28011 MongoDB shell version: 2.0.4
connecting to: 127.0.0.1:28011/test SECONDARY> show dbs admin (empty) local 1.203125GB test 0.203125GB SECONDARY> db test SECONDARY> show collections ----在执行这一行的时候报错 说明这个从库暂时不能执行查询操作 Fri Jul 25 13:40:36 uncaught exception: error: { "$err" : "not master and slaveok=false", "code" : 13435 }步骤三,使从库可以读,以分担主库的压力,代码如下
SECONDARY> db.getMongo().setSlaveOk()
not master and slaveok=false SECONDARY> show dbs admin (empty) local 1.203125GB test 0.203125GB SECONDARY> show collections c1 system.indexes SECONDARY> db.c1.find() { "_id" : ObjectId("53d1ed7cb017538f84368f95"), "age" : 30 } SECONDARY>
故障转移
将主库的端口28012的mongodb进程杀掉,在看看复制集的状态
步骤一:杀掉28012端口的mongodb进程,代码如下
[root@dota ~]# ps aux | grep mongod
root 1523 0.4 4.8 1791408 49420 ? Sl Jul20 29:36 /usr/local/mongodb/bin/mongod --dbpath=/usr/local/mongodb/data --logpath=/usr/local/mongodb/logs/mongo.logs --logappend --fork root 2737 0.0 0.0 103248 800 pts/0 S+ 14:15 0:00 grep mongod root 27933 1.5 4.2 3455684 42988 ? Sl 09:50 4:01 /usr/local/mongodb/bin/mongod --replSet rs1 --keyFile /data/key/r0 --fork --port 28010 --dbpath /data/data/r0 --logpath=/data/log/r0.log --logappend root 27950 0.3 3.6 3441068 36752 ? Sl 09:52 0:55 /usr/local/mongodb/bin/mongod --replSet rs1 --keyFile /data/key/r1 --fork --port 28011 --dbpath /data/data/r1 --logpath=/data/log/r1.log --logappendroot 27967 3.0 3.7 3453368 38072 ? Sl 09:53 7:54 /usr/local/mongodb/bin/mongod --replSet rs1 --keyFile /data/key/r2 --fork --port 28012 --dbpath /data/data/r2 --logpath=/data/log/r2.log --logappend [root@dota ~]# kill -9 27967 [root@dota ~]#步骤2,查看复制集状态,代码如下:
[root@dota ~]# /usr/local/mongodb/bin/mongo --port 28011
MongoDB shell version: 2.0.4 connecting to: 127.0.0.1:28011/test SECONDARY> rs.status() { "set" : "rs1", "date" : ISODate("2014-07-25T06:19:24Z"), "myState" : 2, "syncingTo" : "localhost:28010", "members" : [ { "_id" : 0, "name" : "localhost:28010", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 15356, "optime" : { "t" : 1406266748000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T05:39:08Z"), "lastHeartbeat" : ISODate("2014-07-25T06:19:23Z"), "pingMs" : 0 }, { "_id" : 1, "name" : "localhost:28011", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "optime" : { "t" : 1406266748000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T05:39:08Z"), "self" : true }, { "_id" : 2, "name" : "localhost:28012", "health" : 0, "state" : 8, "stateStr" : "(not reachable/healthy)", "uptime" : 0, "optime" : { "t" : 1406266748000, "i" : 1 }, "optimeDate" : ISODate("2014-07-25T05:39:08Z"), "lastHeartbeat" : ISODate("2014-07-25T06:17:17Z"), "pingMs" : 0, "errmsg" : "socket exception" } ], "ok" : 1 } SECONDARY>上面们可以看到,通过执行rs.status命令查看复制集状态,28012端口mongodb出现异常,状态信息是not reaschable/healthy,说明他已经是一个无效的复制集成员,而系统经过自动选举之后,选举28010端口作为主库,28011端口任然为从库,则有的故障处理机制,能将系统的稳定性和连续性大大提高,解决了藏剑的单点故障问题。