注:mongodb当前版本是3.4.3html
192.168.168.129:27017
192.168.168.130:27017
192.168.168.131:27017node
详细请见linux安装mongodb(设置非root用户和开机启动)linux
三个服务器的mongodb.conf中都须要加入replSet的指定,它们都属于repl1复制集;
replSet中的S必定要大写!mongodb
登入任意一台机器的mongodb执行,由于是全新的复制集,因此能够任意进入一台执行;要是一台有数据,则须要在有数据上执行;要多台有数据则不能初始化。
rs.initiate({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]})
初始化参数说明:
_id:复制集名称(第一个_id)
members:复制集服务器列表
_id:服务器的惟一ID(数组里_id)
host:服务器主机
咱们操做的是192.168.168.129服务器,其中repl1便是复制集名称,和mongodb.conf中保持一致,初始化复制集的第一个服务器将会成为主复制集shell
经过rs.status()查看复制集状态能够看到,192.168.168.129:27017已被自动分配为primary主复制集了
rs.add('192.168.168.130:27017'),增长192.168.168.130为从节点,第一次执行add时报了一个错,这个错说的是找到192.168.168.130服务,是由于防火墙的缘由,咱们把192.168.168.130防火墙关掉(service iptables stop),当第二次执行add的时候就成功了。
注:为了保证复制集中三个服务器之间正常链接,请保证三个服务器的防火墙都已关闭!数组
能够看到192.168.168.130:27017成为了secondary节点
rs.addArb('192.168.168.131:27017')
能够看到192.168.168.131:27017成为了arbiter节点
在primary(192.168.168.129:27017)上插入数据:服务器
repl1:PRIMARY> db
test
repl1:PRIMARY> show collections
repl1:PRIMARY>for(var i =0; i <4; i ++){db.user.insert({userName:'gxt'+i,age:i})}
WriteResult({"nInserted":1})
repl1:PRIMARY> show collections
user
repl1:PRIMARY> db.user.find()
{"_id":ObjectId("5912e308e5c3987e4a8131e2"),"userName":"gxt0","age":0}
{"_id":ObjectId("5912e308e5c3987e4a8131e3"),"userName":"gxt1","age":1}
{"_id":ObjectId("5912e308e5c3987e4a8131e4"),"userName":"gxt2","age":2}
{"_id":ObjectId("5912e308e5c3987e4a8131e5"),"userName":"gxt3","age":3}
repl1:PRIMARY>
在secondary上查看是否已经同步:socket
repl1:SECONDARY> db
test
repl1:SECONDARY> show collections
2017-05-10T03:14:54.665-0700 E QUERY [thread1]Error: listCollections failed:{
"ok":0,
"errmsg":"not master and slaveOk=false",
"code":13435,
"codeName":"NotMasterNoSlaveOk"
}:
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:805:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:817:19
DB.prototype.getCollectionNames@src/mongo/shell/db.js:828:16
shellHelper.show@src/mongo/shell/utils.js:762:9
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1
repl1:SECONDARY> rs.slaveOk()
repl1:SECONDARY> show collections
user
repl1:SECONDARY> db.user.find()
{"_id":ObjectId("5912e308e5c3987e4a8131e2"),"userName":"gxt0","age":0}
{"_id":ObjectId("5912e308e5c3987e4a8131e3"),"userName":"gxt1","age":1}
{"_id":ObjectId("5912e308e5c3987e4a8131e4"),"userName":"gxt2","age":2}
{"_id":ObjectId("5912e308e5c3987e4a8131e5"),"userName":"gxt3","age":3}
repl1:SECONDARY>
经过db.user.find()查询到和主复制集上同样的数据,表示数据同步成功!测试
"errmsg" : "not master and slaveOk=false"错误说明:由于secondary是不容许读写的,若是非要解决,则执行:rs.slaveOk()
在arbiter上查看是否会有数据同步:spa
repl1:ARBITER> db
test
repl1:ARBITER> show collections
2017-05-10T03:22:02.554-0700 E QUERY [thread1]Error: listCollections failed:{
"ok":0,
"errmsg":"not master and slaveOk=false",
"code":13435,
"codeName":"NotMasterNoSlaveOk"
}:
_getErrorWithCode@src/mongo/shell/utils.js:25:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:805:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:817:19
DB.prototype.getCollectionNames@src/mongo/shell/db.js:828:16
shellHelper.show@src/mongo/shell/utils.js:762:9
shellHelper@src/mongo/shell/utils.js:659:15
@(shellhelp2):1:1
repl1:ARBITER> rs.slaveOk()
repl1:ARBITER> show collections
repl1:ARBITER> db.user.find()
Error: error:{
"ok":0,
"errmsg":"node is not in primary or recovering state",
"code":13436,
"codeName":"NotMasterOrSecondary"
}
repl1:ARBITER>
咱们能够看到,arbiter并无进行数据同步,由于仲裁节点只参与投票,不接收数据!
关闭primary节点,查看其它两个节点的状况:
repl1:PRIMARY>use admin
switched to db admin
repl1:PRIMARY> db.shutdownServer()
server should be down...
2017-05-10T03:27:04.162-0700 I NETWORK [thread1] trying reconnect to 127.0.0.1:27017(127.0.0.1) failed
2017-05-10T03:27:04.207-0700 I NETWORK [thread1]Socket recv()Connection reset by peer 127.0.0.1:27017
2017-05-10T03:27:04.208-0700 I NETWORK [thread1]SocketException: remote:(NONE):0 error:9001 socket exception [RECV_ERROR] server [127.0.0.1:27017]
2017-05-10T03:27:04.208-0700 I NETWORK [thread1] reconnect 127.0.0.1:27017(127.0.0.1) failed failed
>
咱们能够看到192.168.168.130:27017从secondary变成了primary,故障转移成功!不过如今这个复制集已没有能够同步数据的从节点了,但咱们能够把192.168.168.129:27017从新启动,这时129会变成secondary,这样这个复制集就能够正常工做了。
rs.initiate():复制集初始化,例如:rs.initiate({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]})
rs.reconfig():从新加载配置文件,例如:
rs.reconfig({_id:'repl1',members:[{_id:1,host:'192.168.168.129:27017'}]},{force:true})当只剩下一个secondary节点时,复制集变得不可用,则能够指定force属性强制将节点变成primary,而后再添加secondary节点
rs.status():查看复制集状态
db.printSlaveReplicationInfo():查看复制状况
rs.conf()/rs.config():查看复制集配置
rs.slaveOk():在当前链接让secondary能够提供读操做
rs.add():增长复制集节点,例如:
rs.add('192.168.168.130:27017')
rs.add({"_id":3,"host":"192.168.168.130:27017","priority":0,"hidden":true})指定hidden属性添加备份节点
rs.add({"_id":3,"host":"192.168.168.130:27017","priority":0,"slaveDelay":60})指定slaveDelay属性添加延迟节点
priority:是优先级,默认为1,若是想手动指定某个节点为primary节点,则把对应节点的priority属性设置为全部节点中最大的一个便可
rs.remove():删除复制集节点,例如:rs.remove('192.168.168.130:27017')
rs.addArb():添加仲裁节点,例如:
rs.addArb('192.168.168.131:27017')或者rs.add({"_id":3,"host":"192.168.168.130:27017","arbiterOnly":true}),仲裁节点,只参与投票,不接收数据
属性说明: