MongoDB副本集調(diào)整節(jié)點(diǎn)
MongoDB的副本集(Replica Set)是一個(gè)高可用性、可擴(kuò)展性和冗余性的數(shù)據(jù)庫解決方案。它能夠確保數(shù)據(jù)庫的高可用性,同時(shí)保障了數(shù)據(jù)的安全性。在本文中,我們將探討如何在一個(gè)已經(jīng)包含三個(gè)數(shù)據(jù)節(jié)點(diǎn)的副本集集群中,添加一個(gè)仲裁節(jié)點(diǎn),并同時(shí)刪除原先的一個(gè)數(shù)據(jù)節(jié)點(diǎn)。
1、副本集的基本概念
MongoDB副本集由多個(gè)數(shù)據(jù)節(jié)點(diǎn)+若干個(gè)仲裁節(jié)點(diǎn)(可以沒有)組成,其中一個(gè)數(shù)據(jù)節(jié)點(diǎn)被選舉為主節(jié)點(diǎn)(Primary),其余節(jié)點(diǎn)為次要節(jié)點(diǎn)(Secondary)。在故障時(shí),副本集會自動進(jìn)行主節(jié)點(diǎn)的切換,確保服務(wù)的高可用性。副本集中的仲裁節(jié)點(diǎn)(Arbiter)不存儲數(shù)據(jù),僅用于選舉過程,幫助副本集進(jìn)行決策。
例如,當(dāng)前配置一個(gè)3節(jié)點(diǎn)的數(shù)據(jù)節(jié)點(diǎn)集群,組件集群命令如下:
> use admin
> rs.initiate( {_id: "test1",members: [{ _id: 0, host: "192.168.122.36:27017" },{ _id: 1, host: "192.168.122.36:27018" },{ _id: 2, host: "192.168.122.36:27019" } ] })
查看狀態(tài):
test1:PRIMARY> use admin
switched to db admin
test1:PRIMARY> rs.status()
{
"set" : "test1",
"date" : ISODate("2023-10-23T02:31:02.345Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
"appliedOpTime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2023-10-23T02:30:54.919Z"),
"lastDurableWallTime" : ISODate("2023-10-23T02:30:54.919Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1698028224, 3),
"lastStableCheckpointTimestamp" : Timestamp(1698028224, 3),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1698028214, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.122.36:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 183,
"optime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T02:30:54Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1698028224, 1),
"electionDate" : ISODate("2023-10-23T02:30:24Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.122.36:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 47,
"optime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T02:30:54Z"),
"optimeDurableDate" : ISODate("2023-10-23T02:30:54Z"),
"lastHeartbeat" : ISODate("2023-10-23T02:31:00.889Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T02:31:01.443Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.122.36:27017",
"syncSourceHost" : "192.168.122.36:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.122.36:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 47,
"optime" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1698028254, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T02:30:54Z"),
"optimeDurableDate" : ISODate("2023-10-23T02:30:54Z"),
"lastHeartbeat" : ISODate("2023-10-23T02:31:00.890Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T02:31:01.446Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.122.36:27017",
"syncSourceHost" : "192.168.122.36:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1698028254, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1698028254, 1)
}
此時(shí)可以用一個(gè)程序驗(yàn)證集群的可用情況:
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
# MongoDB副本集的連接信息
replica_set = "test1"
mongo_host = ["192.168.122.36:27017", "192.168.122.36:27018", "192.168.122.36:27019"] # 主機(jī)和端口號列表
# 嘗試連接MongoDB副本集
try:
client = MongoClient(mongo_host, replicaSet=replica_set, serverSelectinotallow=5000)
db = client["testdb"]
print("Successfully connected to MongoDB replica set.")
collection = db['test1']
data = {"b":2}
result = collection.insert_one(data)
except ConnectionFailure:
print("Failed to connect to MongoDB replica set. Please check your connection settings.")
運(yùn)行結(jié)果如下:
查看數(shù)據(jù)庫中運(yùn)行結(jié)果:
2、添加節(jié)點(diǎn)
要添加一個(gè)仲裁節(jié)點(diǎn),我們需要在現(xiàn)有副本集中的任一節(jié)點(diǎn)上執(zhí)行如下操作:
rs.add( { host: "IP:PORT", arbiterOnly:true } )
執(zhí)行這個(gè)命令后,MongoDB將會在副本集中添加一個(gè)仲裁節(jié)點(diǎn),增加了選主的穩(wěn)定性,同時(shí)不會增加數(shù)據(jù)存儲的壓力。具體實(shí)際案例如下
test1:PRIMARY> use admin
switched to db admin
test1:PRIMARY> rs.add( { host: "192.168.122.36:27020", arbiterOnly:true } )
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1698030806, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1698030806, 1)
}
test1:PRIMARY> rs.status();
{
"set" : "test1",
"date" : ISODate("2023-10-23T03:13:32.511Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 3,
"writeMajorityCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
"appliedOpTime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2023-10-23T03:13:26.379Z"),
"lastDurableWallTime" : ISODate("2023-10-23T03:13:26.379Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1698030805, 1),
"lastStableCheckpointTimestamp" : Timestamp(1698030805, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1698028214, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.122.36:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2733,
"optime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T03:13:26Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1698028224, 1),
"electionDate" : ISODate("2023-10-23T02:30:24Z"),
"configVersion" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.122.36:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2597,
"optime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T03:13:26Z"),
"optimeDurableDate" : ISODate("2023-10-23T03:13:26Z"),
"lastHeartbeat" : ISODate("2023-10-23T03:13:32.393Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.420Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 2
},
{
"_id" : 2,
"name" : "192.168.122.36:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2597,
"optime" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1698030806, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T03:13:26Z"),
"optimeDurableDate" : ISODate("2023-10-23T03:13:26Z"),
"lastHeartbeat" : ISODate("2023-10-23T03:13:32.393Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.445Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 2
},
{
"_id" : 3,
"name" : "192.168.122.36:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 6,
"lastHeartbeat" : ISODate("2023-10-23T03:13:32.405Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T03:13:32.455Z"),
"pingMs" : NumberLong(4),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 2
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1698030806, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1698030806, 1)
}
此時(shí)修改python中程序(插入的數(shù)據(jù)),運(yùn)行結(jié)果如下:
3、刪除數(shù)據(jù)節(jié)點(diǎn)
如果你需要刪除一個(gè)數(shù)據(jù)節(jié)點(diǎn),首先,你要確保副本集的健康狀態(tài),然后執(zhí)行如下操作來刪除一個(gè)Secondary節(jié)點(diǎn)。
rs.remove("IP:PORT");
執(zhí)行這個(gè)命令后,MongoDB將從副本集中移除該數(shù)據(jù)節(jié)點(diǎn),副本集會重新進(jìn)行選舉,確保副本集的高可用性。
test1:PRIMARY> rs.remove("192.168.122.36:27019")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1698038888, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1698038888, 1)
}
test1:PRIMARY> rs.status
function() {
return db._adminCommand("replSetGetStatus"); # 選舉中
}
test1:PRIMARY> rs.status()
{
"set" : "test1",
"date" : ISODate("2023-10-23T05:28:15.398Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
"appliedOpTime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2023-10-23T05:28:08.335Z"),
"lastDurableWallTime" : ISODate("2023-10-23T05:28:08.335Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1698038845, 1),
"lastStableCheckpointTimestamp" : Timestamp(1698038845, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2023-10-23T02:30:24.838Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1698028214, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2023-10-23T02:30:24.912Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2023-10-23T02:30:25.497Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.122.36:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 10816,
"optime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T05:28:08Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1698028224, 1),
"electionDate" : ISODate("2023-10-23T02:30:24Z"),
"configVersion" : 3,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.122.36:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 10680,
"optime" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1698038888, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-10-23T05:28:08Z"),
"optimeDurableDate" : ISODate("2023-10-23T05:28:08Z"),
"lastHeartbeat" : ISODate("2023-10-23T05:28:14.347Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T05:28:15.388Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
},
{
"_id" : 3,
"name" : "192.168.122.36:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 8088,
"lastHeartbeat" : ISODate("2023-10-23T05:28:14.342Z"),
"lastHeartbeatRecv" : ISODate("2023-10-23T05:28:14.369Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 3
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1698038888, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1698038888, 1)
}
注意:復(fù)制集將會短暫的關(guān)閉連接并進(jìn)入選舉,選舉出一個(gè)新的主節(jié)點(diǎn)。接口將會自動重連。接口可能將會報(bào)錯(cuò) DBClientCursor::init call() failed 。