MongoDB 副本集(类似高可用)
1.节点类型
standard:常规节点,它存储一份完整的数据副本,参与选举投票,有可能成为活跃节点。
passive:存储了完整的数据副本,参与投票,不能成为活跃节点。
arbiter:仲裁节点,只参与投票,不接收复制的数据,也不能成为活跃节点。
2.参数说明
--dbpath 数据文件路径
--logpath 日志文件路径
--port 端口号,默认是27017.我这里使用的也是这个端口号.
--replSet 复制集的名字,一个replica sets中的每个节点的这个参数都要用一个复制集名字,这里是1905.
--replSet 这个后面跟的是其他standard节点的ip和端口
--maxConns 最大连接数
--fork 后台运行
--logappend 日志文件循环使用,如果日志文件已满,那么新日志覆盖最久日志。
3.创建副本集
环境说明:
ip:192.168.3.206 #standard节点
ip:192.168.3.210 #standard节点
ip:192.168.3.201 #仲裁节点
4.安装方法
参照http://blog.****.net/liu331095659/article/details/37870323来安装。安装成功后,不要用博客上面的启动命令。
5.启动方法
启动第一个standard节点(ip:192.168.3.206)
/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb/ --logpath /data/logs/mongodb/log.log --logappend --port=27017 -replSet 1905 -maxConns=2000 -fork
启动第一个standard节点(ip:192.168.3.210)
/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb/ --logpath /data/logs/mongodb/log.log --logappend --port=27017 -replSet 1905 -maxConns=2000 -fork
启动arbiter节点,也就是仲裁节点 (ip:192.168.3.201)
/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb/ --logpath /data/logs/mongodb/log.log --logappend --port=27017 -replSet 1905 -maxConns=2000 -fork
6.shell初始化副本集
启动了以上服务器后,日志告诉你副本集没有初始化。
连接其中一台standard(192.168.3.206)节点服务器。初始化命令只能执行一次
db.runCommand({"replSetInitiate" : {
"_id" : "1905",
"members" : [
{
"_id" : 0,
"host" : "192.168.3.206:27017"
},
{
"_id" : 1,
"host" : "192.168.3.210:27017"
}
]}})
rs.status()
{
"startupStatus" : 3,
"info" : "run rs.initiate(...) if not yet done for the set",
"ok" : 0,
"errmsg" : "can‘t get local.system.replset config from self or any seed (EMPTYCONFIG)"
}
如果通过rs.status()得到上面结果。说明还没有得到副本集合的配置信息,然后执行下面语句
config_rs={_id:‘1905‘,members:[{_id:0,host:‘192.168.3.206:27017‘},{_id:1,host:‘192.168.3.210:27017‘}]}
rs.initiate(config_rs);
{
"info" : "Config now saved locally. Should come online in about a minute.",
"ok" : 1
}
表示已经得到副本集合了。
7.测试副本集
7.1查看副本集合
rs.status()
{
"set" : "1905",
"date" : ISODate("2014-07-16T03:11:53Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.3.206:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 4777,
"optime" : Timestamp(1405480230, 1),
"optimeDate" : ISODate("2014-07-16T03:10:30Z"),
"electionTime" : Timestamp(1405480240, 1),
"electionDate" : ISODate("2014-07-16T03:10:40Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.3.210:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 81,
"optime" : Timestamp(1405480230, 1),
"optimeDate" : ISODate("2014-07-16T03:10:30Z"),
"lastHeartbeat" : ISODate("2014-07-16T03:11:53Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T03:11:53Z"),
"pingMs" : 0,
"syncingTo" : "192.168.3.206:27017"
}
],
"ok" : 1
}
7.2加入仲裁节点
执行以下命令:
rs.addArb("192.168.3.201:27017");
{ "ok" : 1 }
我们可以再次查看当前状态:
rs.status()
{
"set" : "1905",
"date" : ISODate("2014-07-16T03:18:58Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.3.206:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 5202,
"optime" : Timestamp(1405480659, 1),
"optimeDate" : ISODate("2014-07-16T03:17:39Z"),
"electionTime" : Timestamp(1405480240, 1),
"electionDate" : ISODate("2014-07-16T03:10:40Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.3.210:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 506,
"optime" : Timestamp(1405480659, 1),
"optimeDate" : ISODate("2014-07-16T03:17:39Z"),
"lastHeartbeat" : ISODate("2014-07-16T03:18:58Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T03:18:58Z"),
"pingMs" : 0,
"syncingTo" : "192.168.3.206:27017"
},
{
"_id" : 2,
"name" : "192.168.3.201:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 79,
"lastHeartbeat" : ISODate("2014-07-16T03:18:57Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T03:18:58Z"),
"pingMs" : 0
}
],
"ok" : 1
}
rs.status()通过这个命令,可以查看各个节点的ip、角色已经是否正常
我们看到已经成功配置。
7.3查看活跃节点:
db.isMaster();
{
"setName" : "1905",
"setVersion" : 2,
"ismaster" : true,
"secondary" : false,
"hosts" : [
"192.168.3.206:27017",
"192.168.3.210:27017"
],
"arbiters" : [
"192.168.3.201:27017"
],
"primary" : "192.168.3.206:27017",
"me" : "192.168.3.206:27017",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2014-07-16T03:23:18.798Z"),
"maxWireVersion" : 2,
"minWireVersion" : 0,
"ok" : 1
}
可以看到现在192.168.3.206:27017为活跃节点。
检测是否配置成功
7.4模拟故障
可以强制primary和standard节点角色互换,从而验证是否能够实现副本集功能
进入主节点后执行下面命令
rs.stepDown()
执行完成后:
db.isMaster()
{
"setName" : "1905",
"setVersion" : 2,
"ismaster" : false,
"secondary" : true,
"hosts" : [
"192.168.3.206:27017",
"192.168.3.210:27017"
],
"arbiters" : [
"192.168.3.201:27017"
],
"primary" : "192.168.3.210:27017",
"me" : "192.168.3.206:27017",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 1000,
"localTime" : ISODate("2014-07-16T03:43:25.102Z"),
"maxWireVersion" : 2,
"minWireVersion" : 0,
"ok" : 1
}
可以看到现在主节点已经修改为192.168.3.210:27017了。
8.动态扩展增加节点
为了节约服务器,我们在ip:192.168.3.210上面重新增加端口27027为standard节点
mkdir -p /data/mongodb1 #27027端口数据目录
mkdir -p /data/logs/mongodb1/ #27027端口日志目录
#启动27027端口standard节点
/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb1/ --logpath /data/logs/mongodb1/log.log --logappend --port=27027 -replSet 1905 -maxConns=2000 -fork
进入活跃节点的服务器
rs.add("192.168.3.210:27027");
{ "ok" : 1 }
我们可以再次查看当前状态:
rs.status()
{
"set" : "1905",
"date" : ISODate("2014-07-16T05:55:37Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.3.206:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 838,
"optime" : Timestamp(1405490134, 1),
"optimeDate" : ISODate("2014-07-16T05:55:34Z"),
"electionTime" : Timestamp(1405489678, 1),
"electionDate" : ISODate("2014-07-16T05:47:58Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.3.210:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 314,
"optime" : Timestamp(1405490134, 1),
"optimeDate" : ISODate("2014-07-16T05:55:34Z"),
"lastHeartbeat" : ISODate("2014-07-16T05:55:36Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T05:55:37Z"),
"pingMs" : 0,
"syncingTo" : "192.168.3.206:27017"
},
{
"_id" : 2,
"name" : "192.168.3.201:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 836,
"lastHeartbeat" : ISODate("2014-07-16T05:55:35Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T05:55:35Z"),
"pingMs" : 0
},
{
"_id" : 3,
"name" : "192.168.3.210:27027",
"health" : 1,
"state" : 5,
"stateStr" : "STARTUP2",
"uptime" : 3,
"optime" : Timestamp(0, 0),
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2014-07-16T05:55:36Z"),
"lastHeartbeatRecv" : ISODate("1970-01-01T00:00:00Z"),
"pingMs" : 0
}
],
"ok" : 1
}
已经出现192.168.3.210:27027说明动态增加节点成功。
9.动态扩展删除节点
进入活跃节点的服务器
rs.remove("192.168.3.210:27027");
2014-07-16T14:00:10.118+0800 DBClientCursor::init call() failed
2014-07-16T14:00:10.119+0800 Error: error doing query: failed at src/mongo/shell/query.js:81
2014-07-16T14:00:10.121+0800 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2014-07-16T14:00:10.122+0800 reconnect 127.0.0.1:27017 (127.0.0.1) ok
我们可以再次查看当前状态:
rs.status()
{
"set" : "1905",
"date" : ISODate("2014-07-16T06:00:31Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "192.168.3.206:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1132,
"optime" : Timestamp(1405490410, 1),
"optimeDate" : ISODate("2014-07-16T06:00:10Z"),
"electionTime" : Timestamp(1405489678, 1),
"electionDate" : ISODate("2014-07-16T05:47:58Z"),
"self" : true
},
{
"_id" : 1,
"name" : "192.168.3.210:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 21,
"optime" : Timestamp(1405490410, 1),
"optimeDate" : ISODate("2014-07-16T06:00:10Z"),
"lastHeartbeat" : ISODate("2014-07-16T06:00:30Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T06:00:29Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "syncing to: 192.168.3.206:27017",
"syncingTo" : "192.168.3.206:27017"
},
{
"_id" : 2,
"name" : "192.168.3.201:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 21,
"lastHeartbeat" : ISODate("2014-07-16T06:00:30Z"),
"lastHeartbeatRecv" : ISODate("2014-07-16T06:00:30Z"),
"pingMs" : 2
}
],
"ok" : 1
}
192.168.3.210:27027已经没有出现在副本集合里面,说明删除节点成功。
10.为主节点模拟写数据
10.1在主节点上面操作
use mytest
> db.test03.insert({age:26})
WriteResult({ "nInserted" : 1 })
> db.test03.find()
{ "_id" : ObjectId("53c4f9dd7f7a3afaa3dd2415"), "age" : 26 }
10.2在从节点上面操作
show dbs;
admin (empty)
local 1.078GB
mytest 0.078GB
#mytest数据库已经自动同步OK
show tables;
2014-07-16T14:17:21.849+0800 error: { "$err" : "not master and slaveOk=false", "code" : 13435 } at src/mongo/shell/query.js:131
#上面提示从节点不能读,所以不能查看集合。
rs.slaveOk() #执行此命令允许从节点可以读取,但是不能写。
show tables;
system.indexes
test03
db.test03.find()
{ "_id" : ObjectId("53c60edaf2c66b02d9c99338"), "age" : 26 }
本文出自 “成都@阿状” 博客,请务必保留此出处http://azhuang.blog.51cto.com/9176790/1440162