MongoDB副本集三节点包含主节点(Primary)、副本节点(Secondary)、仲裁节点(Arbiter)。主节点(primary)负责整个副本集的读写,用户也可根据业务需求情况设置全部或部分读请求到副本节点(Secondary);副本集实时同步数据,如果主节点出现故障或宕机,副本节点就会选举一个新的主节点,这一切对于应用服务器不需关心。仲裁节点不存储数据,只负责故障转移的群体投票,这样就少了数据复制的压力。
本次实验中,我们通过在一台机器上运行3个实例来搭建一个最简单的复制集。通过实验,我们将学会:
(1)如何启动一个 MongoDB 实例
(2)如何将3个 MongoDB 实例搭建成一个复制集
(3)如何对复制集运行参数做一些常规调整
(1)创建数据目录:MongoDB 启动时将使用一个数据目录存放所有数据文件。我们将为3个复制集节点创建各自的数据目录。
mkdir -p /data/db{1,2,3}
(2)准备配置文件
复制集的每个mongod进程应该位于不同的服务器。我们现在在一台机器上运行3个进程,因此要为它们各自配置:
不同的端口。 示例中将使用28017/28018/28019
不同的数据目录。 示例中将使用:
/data/db1
/data/db2
/data/db3
不同日志文件路径。示例中将使用:
/data/db1/mongod.log
/data/db2/mongod.log
/data/db3/mongod.log
[root@10-9-159-73 ~]# vim /data/db1/mongod.conf
systemLog:
destination: file
path: /data/db1/mongod.log # log path
logAppend: true
storage:
dbPath: /data/db1 # data directory
net:
bindIp: 0.0.0.0
port: 28017 # port
replication:
replSetName: rs0
processManagement:
fork: true
(1)启动多个MongoDB实例
mongod -f /data/db1/mongod.conf
mongod -f /data/db2/mongod.conf
mongod -f /data/db3/mongod.conf
(2)查看端口监听情况
[root@10-9-159-73 ~]# netstat -antulp |grep mongod
tcp 0 0 0.0.0.0:28017 0.0.0.0:* LISTEN 140963/mongod
tcp 0 0 0.0.0.0:28018 0.0.0.0:* LISTEN 140989/mongod
tcp 0 0 0.0.0.0:28019 0.0.0.0:* LISTEN 141021/mongod
(3)查看进程情况
[root@10-9-159-73 ~]# ps -ef |grep mongod
root 140963 1 1 15:08 ? 00:00:00 mongod -f /data/db1/mongod.conf
root 140989 1 1 15:08 ? 00:00:00 mongod -f /data/db2/mongod.conf
root 141021 1 0 15:08 ? 00:00:00 mongod -f /data/db3/mongod.conf
[root@10-9-159-73 ~]# hostname -f
10-9-159-73
【注意】此方式hostname 需要能被解析。
(1)初始化副本集
[root@10-9-159-73 ~]# mongo --port 28017
MongoDB shell version v4.2.1
connecting to: mongodb://127.0.0.1:28017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("740e54ef-4919-4c7b-8872-9f7db11806ca") }
MongoDB server version: 4.2.1
> rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "10-9-159-73:28017",
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1650614732, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
rs0:OTHER> # 进入复制集状态
rs0:PRIMARY> # 变成了主节点
(2)添加副本集从节点
rs0:PRIMARY> rs.add("10-9-159-73:28018")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1650614803, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1650614803, 1)
}
(3)添加副本集哨兵arbiter节点
rs0:PRIMARY> rs.addArb("10-9-159-73:28019")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1650615573, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1650615573, 1)
}
(4)查看副本集状态
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2022-04-22T08:33:53.524Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2022-04-22T08:33:47.259Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2022-04-22T08:33:47.259Z"),
"appliedOpTime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2022-04-22T08:33:47.259Z"),
"lastDurableWallTime" : ISODate("2022-04-22T08:33:47.259Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1650616414, 1),
"lastStableCheckpointTimestamp" : Timestamp(1650616414, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2022-04-22T08:31:36.227Z"),
"termAtElection" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1650616296, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 1,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"newTermStartDate" : ISODate("2022-04-22T08:31:37.239Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2022-04-22T08:31:37.249Z")
},
"members" : [
{
"_id" : 0,
"name" : "10-9-159-73:28017",
"ip" : "127.0.0.1",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY", # 主节点
"uptime" : 161,
"optime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-04-22T08:33:47Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1650616296, 2),
"electionDate" : ISODate("2022-04-22T08:31:36Z"),
"configVersion" : 5,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "10-9-159-73:28018",
"ip" : "127.0.0.1",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY", # 从节点
"uptime" : 125,
"optime" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1650616427, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-04-22T08:33:47Z"),
"optimeDurableDate" : ISODate("2022-04-22T08:33:47Z"),
"lastHeartbeat" : ISODate("2022-04-22T08:33:52.591Z"),
"lastHeartbeatRecv" : ISODate("2022-04-22T08:33:52.632Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10-9-159-73:28017",
"syncSourceHost" : "10-9-159-73:28017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 5
},
{
"_id" : 2,
"name" : "10-9-159-73:28019",
"ip" : "127.0.0.1",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER", # 哨兵选举节点
"uptime" : 18,
"lastHeartbeat" : ISODate("2022-04-22T08:33:52.599Z"),
"lastHeartbeatRecv" : ISODate("2022-04-22T08:33:52.643Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 5
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1650616427, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1650616427, 1)
}
[root@10-9-159-73 ~]# mongo --port 28017
> rs.initiate({
_id: "rs0",
members: [{
_id: 0,
host: "localhost:28017"
},{
_id: 1,
host: "localhost:28018"
},{
_id: 2,
host: "localhost:28019"
}]
})
(1)MongoDB 主节点进行写入
[root@10-9-159-73 ~]# mongo localhost:28017
rs0:PRIMARY> db.test.insert({ a:1 })
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.insert({ a:2 })
WriteResult({ "nInserted" : 1 })
(2)MongoDB 从节点进行读
[root@10-9-159-73 ~]# mongo localhost:28018
rs0:SECONDARY> db.test.find() # 默认从节点是不允许读的,所以会报错
Error: error: {
"operationTime" : Timestamp(1624114510, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : "NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1624114510, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
rs0:SECONDARY> rs.slaveOk() # 允许从节点读
rs0:SECONDARY> db.test.find() # 主库写的两条数据已经同步了
{ "_id" : ObjectId("60ce051bd01aaec374883398"), "a" : 1 }
{ "_id" : ObjectId("60ce0520d01aaec374883399"), "a" : 2 }
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。