1. 准備工作
有一套mongodb 副本集的集群,部署方式參考 mongodb 4.0副本集搭建
准備一個新節點,使用和原副本集版本一致的mongodb
拷貝原副本集中的配置文件、keyfile文件,並注意修改keyfile文件的權限(600)
| 節點 |
角色 |
| 192.168.56.199:27017 | PRIMARY |
| 192.168.56.198:27018 | SECONDARY |
| 192.168.56.199:27018 | ARBITER |
准備加入的新節點: 192.168.56.197:27017
2. 添加節點
2.1 啟動新節點
例如,原節點的版本是4.2.8,新節點版本一致,路徑一致,然后啟動新節點
/usr/local/mongodb/bin/mongod -f /data/mongodb/27017/etc/mongodb.conf
2.2 主庫上查看當前節點及配置信息
使用rs.config()查看配置信息
test12:PRIMARY> rs.config() { "_id" : "test12", "version" : 1, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.56.198:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.56.199:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.56.199:27018", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("61b86af0a21015e69623e18d") } }
rs.status() 查看狀態信息
test12:PRIMARY> rs.status() { "set" : "test12", "date" : ISODate("2021-12-14T10:07:46.561Z"), "myState" : 1, "term" : NumberLong(1), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2021-12-14T10:07:42.560Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2021-12-14T10:07:42.560Z"), "appliedOpTime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2021-12-14T10:07:42.560Z"), "lastDurableWallTime" : ISODate("2021-12-14T10:07:42.560Z") }, "lastStableRecoveryTimestamp" : Timestamp(1639476442, 1), "lastStableCheckpointTimestamp" : Timestamp(1639476442, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2021-12-14T09:59:22.407Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1639475952, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 2, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "numCatchUpOps" : NumberLong(0), "newTermStartDate" : ISODate("2021-12-14T09:59:22.431Z"), "wMajorityWriteAvailabilityDate" : ISODate("2021-12-14T09:59:23.493Z") }, "members" : [ { "_id" : 0, "name" : "192.168.56.198:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 514, "optime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-12-14T10:07:42Z"), "optimeDurableDate" : ISODate("2021-12-14T10:07:42Z"), "lastHeartbeat" : ISODate("2021-12-14T10:07:45.153Z"), "lastHeartbeatRecv" : ISODate("2021-12-14T10:07:46.542Z"), "pingMs" : NumberLong(1), "lastHeartbeatMessage" : "", "syncingTo" : "192.168.56.199:27017", "syncSourceHost" : "192.168.56.199:27017", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 1 }, { "_id" : 1, "name" : "192.168.56.199:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1001, "optime" : { "ts" : Timestamp(1639476462, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-12-14T10:07:42Z"), "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1639475962, 1), "electionDate" : ISODate("2021-12-14T09:59:22Z"), "configVersion" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 2, "name" : "192.168.56.199:27018", "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 514, "lastHeartbeat" : ISODate("2021-12-14T10:07:44.896Z"), "lastHeartbeatRecv" : ISODate("2021-12-14T10:07:44.896Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncingTo" : "", "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "configVersion" : 1 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1639476462, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1639476462, 1) }
2.3 將新節點添加至集群
在主庫上執行rs.add()將新節點添加進集群中
生產環境添加節點時,建議將priority及votes設為0,即不會選為主(priority默認1),也沒有投票特性(votes默認1,有投票權)
test12:PRIMARY> rs.add( { host: "192.168.56.197:27017", priority: 0, votes: 0 } )
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1639476997, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1639476997, 1)
}
另外,生產環境是從主庫拉取全量數據,如果數據量較大,則需要觀察主庫的壓力及對線上業務的影響。
同步數據的過程中,新節點的狀態stateStr 為STARTUP2,待同步完成后會變為SECONDARY。
2.4 重置新節點的屬性
此時再用rs.config()查看新節點狀態,priority及votes是之前設的0,可以使用 rs.recofig()命令進行調整
test12:PRIMARY> rs.config() { "_id" : "test12", "version" : 2, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.56.198:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.56.199:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.56.199:27018", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "192.168.56.197:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 0 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("61b86af0a21015e69623e18d") } }
從上面可以看到新節點的id為3 ,則可以通過如下命令調整對應的屬性
var cfg = rs.conf() cfg.members[3].priority = 1 cfg.members[3].votes = 1 rs.reconfig(cfg)
調整后再查看,屬性已調整
test12:PRIMARY> rs.config() { "_id" : "test12", "version" : 3, "protocolVersion" : NumberLong(1), "writeConcernMajorityJournalDefault" : true, "members" : [ { "_id" : 0, "host" : "192.168.56.198:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "192.168.56.199:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "192.168.56.199:27018", "arbiterOnly" : true, "buildIndexes" : true, "hidden" : false, "priority" : 0, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 3, "host" : "192.168.56.197:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : -1, "catchUpTakeoverDelayMillis" : 30000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("61b86af0a21015e69623e18d") } }
至此,新節點便加入了副本集中
3. 注意點總結
-
一個副本集,最多可以擁有50個secondary,最多可以有7個投票成員,在副本集里面添加一個新成員,如果之前副本集已經有了7個成員,那么可以設置成非投票成員,或者你從移除之前一個投票成員出來
-
新節點的版本、配置建議與原集群一致
-
注意添加新節點前確定網絡互通
-
如果集群數據量較大,則選擇業務低峰期添加節點,並觀察壓力情況
-
新節點加入時建議將priority及votes設為0
