MongoDB副本集调整节点
MongoDB的副本集(Replica Set)是一个高可用性、可扩展性和冗余性的数据库解决方案。它能够确保数据库的高可用性,同时保障了数据的安全性。在本文中,我们将探讨如何在一个已经包含三个数据节点的副本集集群中,添加一个仲裁节点,并同时删除原先的一个数据节点。
1. 副本集的基本概念
MongoDB副本集由多个数据节点+若干个仲裁节点(可以没有)组成,其中一个数据节点被选举为主节点(Primary),其余节点为次要节点(Secondary)。在故障时,副本集会自动进行主节点的切换,确保服务的高可用性。副本集中的仲裁节点(Arbiter)不存储数据,仅用于选举过程,帮助副本集进行决策。
例如,当前配置一个3节点的数据节点集群,组件集群命令如下:
> 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" } ] })

查看状态:
test1:PRIMARY> use adminswitched to db admintest1: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)}
此时可以用一个程序验证集群的可用情况:
from pymongo import MongoClientfrom 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"] # 主机和端口号列表# 尝试连接MongoDB副本集try:client = MongoClient(mongo_host, replicaSet=replica_set, serverSelectionTimeoutMS=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.")
运行结果如下:

查看数据库中运行结果:

2. 添加节点
要添加一个仲裁节点,我们需要在现有副本集中的任一节点上执行如下操作:
rs.add( { host: "IP:PORT", arbiterOnly:true } )
test1:PRIMARY> use adminswitched to db admintest1: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)}
此时修改python中程序(插入的数据),运行结果如下:

3. 删除数据节点
如果你需要删除一个数据节点,首先,你要确保副本集的健康状态,然后执行如下操作来删除一个Secondary节点。
rs.remove("IP:PORT");
执行这个命令后,MongoDB将从副本集中移除该数据节点,副本集会重新进行选举,确保副本集的高可用性。
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.statusfunction() {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)}
注意:复制集将会短暂的关闭连接并进入选举,选举出一个新的主节点。接口将会自动重连。接口可能将会报错 DBClientCursor::init call() failed 。
2. mysql8.0新增用户及加密规则修改的那些事
3. 比hive快10倍的大数据查询利器-- presto
4. 监控利器出鞘:Prometheus+Grafana监控MySQL、Redis数据库
5. PostgreSQL主从复制--物理复制
6. MySQL传统点位复制在线转为GTID模式复制
评论
