環境
因資源有限,故本實驗是在同一臺機器上創建不同實例來完成
master:192.168.65.130 port:27018
secondary:192.168.65.130 port:27019
arbiter:192.168.65.130 port:27020
多實例安裝
方法與單實例基本相同,參考 https://blog.csdn.net/qq_31144297/article/details/107012909
配置文件
dbpath=/mongodb/27018/data
logpath=/mongodb/27018/logs/mongodb.log
port=27018
fork=true
#auth=true
#noauth=true
#verbose=true
#vvvv=true
journal=true
maxConns=500
logappend=true
directoryperdb=true
pidfilepath=/tmp/mongo_27018.pid
#cpu=true
#nohttpinterface=false
#notablescan=false
#profile=0
#slowms=200
#quiet=true
#syncdelay=60
replSet=ty
bind_ip=127.0.0.1,192.168.65.130
ps:replSet 爲複製集名稱,所有實例的該值一定要相同
將其中的文件路徑和端口相關的值修改爲對應的實例即可。
啓動實例
mongod --config /mongodb/27018/logs/mongodb.log
mongod --config /mongodb/27019/logs/mongodb.log
mongod --config /mongodb/27020/logs/mongodb.log
初始化主節點
rs.initiate({_id:'ty',members:[{_id:1,host:'192.168.65.130:27018'}]})
添加節點及仲裁節點
rs.add("192.168.65.130:27019")
rs.addArb("192.168.65.130:27020")
PS:或者以上2可以合成一步,如下:
mongo -port 27018
> cfg={ _id:"rss", members:[ {_id:0,host:'192.168.65.130:27018',priority:2}, {_id:1,host:'192.168.65.130:27019',priority:1}, {_id:2,host:'192.168.65.130:27020',arbiterOnly:true}] };
初始化:> rs.initiate(cfg)
查看配置
rs.conf()
檢查各個節點local庫信息
複製集工作原理:
複製集通過local庫下的oplog.rs集合進行數據同步。
oplog會包含所有對數據有修改的操作(查詢操作不會記錄)
mongo 192.168.65.130:27019
use local
show collections
mongo 192.168.65.130:27020
use local
show collections
檢查複製集狀態
rs.status()
數據驗證
主庫添加數據
[mongodb@ty1 ~]$ mongo --port 27018
ty:PRIMARY> db.ty.insert({age:100})
WriteResult({ "nInserted" : 1 })
ty:PRIMARY> db.ty.find()
{ "_id" : ObjectId("5ef9a99662e0d2208ccde0cc"), "ty" : 11 }
{ "_id" : ObjectId("5efa8adc3b55e73f44c6539e"), "age" : 100 }
從庫查詢
[mongodb@ty1 ~]$ mongo --port 27019
ty:SECONDARY> db.ty.find()
Error: error: {
"operationTime" : Timestamp(1593477663, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1593477663, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
如果出現上面的提示:not master and slaveOkfalse
則執行 db.getMongo().setSlaveOk()
然後在查詢
ty:SECONDARY> db.ty.find()
{ "_id" : ObjectId("5ef9a99662e0d2208ccde0cc"), "ty" : 11 }
{ "_id" : ObjectId("5efa8adc3b55e73f44c6539e"), "age" : 100 }
故障轉移
1.記錄故障轉移之前的狀態
"members" : [
{
"_id" : 1,
"name" : "192.168.65.130:27018",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 58483,
"optime" : {
"ts" : Timestamp(1593478263, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-06-30T00:51:03Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1593419794, 1),
"electionDate" : ISODate("2020-06-29T08:36:34Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.65.130:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 58377,
"optime" : {
"ts" : Timestamp(1593478263, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1593478263, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2020-06-30T00:51:03Z"),
"optimeDurableDate" : ISODate("2020-06-30T00:51:03Z"),
"lastHeartbeat" : ISODate("2020-06-30T00:51:11.969Z"),
"lastHeartbeatRecv" : ISODate("2020-06-30T00:51:11.969Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.65.130:27018",
"syncSourceHost" : "192.168.65.130:27018",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 3
},
{
"_id" : 3,
"name" : "192.168.65.130:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 58370,
"lastHeartbeat" : ISODate("2020-06-30T00:51:12.334Z"),
"lastHeartbeatRecv" : ISODate("2020-06-30T00:51:12.055Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1593478263, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1593478263, 1)
}
2.手動停止27018(主服務)
ty:PRIMARY> use admin
switched to db admin
ty:PRIMARY> db.shutdownServer()
[mongodb@ty1 ~]$ ps -ef|grep mongo
mongodb 12563 1 1 Jun29 ? 00:11:02 mongod --config /mongodb/27019/mongodb_27019.conf
mongodb 12605 1 0 Jun29 ? 00:07:27 mongod --config /mongodb/27020/mongodb_27020.conf
mongodb 22114 12839 0 08:42 pts/2 00:00:00 mongo --port 27019
3.連入其他節點
[mongodb@ty1 ~]$ mongo --port 27019
ty:PRIMARY>
當連入27019 對應的實例時,提示符已經顯示的是 Primary 。
4.檢查複製集狀態
"members" : [
{
"_id" : 1,
"name" : "192.168.65.130:27018",
"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("2020-06-30T00:56:30.323Z"),
"lastHeartbeatRecv" : ISODate("2020-06-30T00:53:02.027Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Error connecting to 192.168.65.130:27018 :: caused by :: Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 2,
"name" : "192.168.65.130:27019",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 58787,
"optime" : {
"ts" : Timestamp(1593478582, 1),
"t" : NumberLong(3)
},
"optimeDate" : ISODate("2020-06-30T00:56:22Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1593478382, 1),
"electionDate" : ISODate("2020-06-30T00:53:02Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 3,
"name" : "192.168.65.130:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 58688,
"lastHeartbeat" : ISODate("2020-06-30T00:56:30.229Z"),
"lastHeartbeatRecv" : ISODate("2020-06-30T00:56:30.208Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1593478582, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1593478582, 1)
}
可以看到狀態信息中stateStr欄位,主節點的從 primary 變成了 (not reachable/healthy) , SECONDARY 節點從 SECONDARY 變成了 primary,說明完成自動切換任務
5.寫入測試
ty:PRIMARY> db.ty.insert({age:1000})
WriteResult({ "nInserted" : 1 })
ty:PRIMARY> db.ty.find()
{ "_id" : ObjectId("5ef9a99662e0d2208ccde0cc"), "ty" : 11 }
{ "_id" : ObjectId("5efa8adc3b55e73f44c6539e"), "age" : 100 }
{ "_id" : ObjectId("5efa8ed6d009f8bab0438011"), "age" : 1000 }
讀寫正常
6.故障節點重新啓動
[mongodb@ty1 ~]$ mongod --config /mongodb/27018/mongodb_27018.conf
about to fork child process, waiting until server is ready for connections.
forked process: 22362
child process started successfully, parent exiting
[mongodb@ty1 ~]$ mongo --port 27018
則該節點角色將變爲secondary,且自動複製最新的數據到本節點
ty:SECONDARY> db.getMongo().setSlaveOk()
ty:SECONDARY> db.ty.find();
{ "_id" : ObjectId("5ef9a99662e0d2208ccde0cc"), "ty" : 11 }
{ "_id" : ObjectId("5efa8adc3b55e73f44c6539e"), "age" : 100 }
{ "_id" : ObjectId("5efa8ed6d009f8bab0438011"), "age" : 1000 }
添加節點
1.配置新實例
2.添加新實例
a.連接主節點
b.添加節點
rs.add("192.168.65.130:27021")
3.查看配置
4.數據驗證
刪除節點
rs.remove("192.168.65.130:27021")