1.mongodb副本简介
MongoDB 副本集(Replica Set)包括主节点(primary)跟副本节点(Secondaries)。主节点只能有一个,所有的写操作请求都在主节点上面处理。副本节点可以有多个,通过同步主节点的操作日志(oplog)来备份主节点数据。
在主节点挂掉后,有选举权限的副本节点会自动发起选举,并从中选举出新的主节点。副本节点可以通过配置,指定其具体的属性,比如选举、隐藏、延迟同步等,最多可以有50个副本节点,但只能有7个副本节点能参与选举。虽然副本节点不能处理写操作,但可以处理读请求。
搭建一个副本集集群最少需要三个节点:一个主节点,两个备份节点,三个节点的架构如下图所示:
2.服务架构
搭建一套3节点副本集(1个 Primary 节点,2个 Secondary 节点),节点规划如下:
主机名 | ip | 角色 |
---|---|---|
ppgroup-mongo-redis01 | 172.17.0.78 | primary |
Ppgroup-mongo-redis02 | 172.17.0.77 | secondary |
Ppgroup-mongo-redis03 | 172.17.0.76 | secondary |
3.部署服务
配置hosts解析
cat >> /etc/hosts <<EOF
172.17.0.78 ppgroup-mongo-redis01
172.17.0.77 ppgroup-mongo-redis02
172.17.0.76 ppgroup-mongo-redis03
EOF
关闭防火墙和selinux
systemctl disable firewalld
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config && setenforce 0
配置国内yum源
cat > /etc/yum.repos.d/mongodb.repo <<'EOF'
[mongodb-org]
name=MongoDB Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/mongodb/yum/el$releasever/
gpgcheck=0
enabled=1
EOF
所有节点安装mongo
yum install -y mongodb-org
修改mongo配置文件一下内容
# mongod.conf
# for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
#日志目录
# Where and how to store data.
storage:
dbPath: /data/mongo
#数据库存放目录
journal:
enabled: true
# engine:
# wiredTiger:
# how the process runs
processManagement:
fork: true # fork and run in background
pidFilePath: /var/run/mongodb/mongod.pid # location of pidfile
timeZoneInfo: /usr/share/zoneinfo
# network interfaces
net:
port: 27017
bindIp: 0.0.0.0 # Enter 0.0.0.0,:: to bind to all IPv4 and IPv6 addresses or, alternatively, use the net.bindIpAll setting.
#security:
#operationProfiling:
replication:
replSetName: "rs0"
#开启副本集配置
#sharding:
## Enterprise-Only Options
#auditLog:
#snmp:
启动服务
systemctl enable mongod
systemctl start mongod
4.配置复制集群
master节点操作初始化集群
mongo
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "ppgroup-mongo-redis01:27017" },
{ _id: 1, host: "ppgroup-mongo-redis02:27017" },
{ _id: 2, host: "ppgroup-mongo-redis03:27017" }
]
})
查看集群状态
rs.status()
{
"set" : "rs0",
"date" : ISODate("2022-08-08T09:14:30.930Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"votingMembersCount" : 3,
"writableVotingMembersCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastDurableWallTime" : ISODate("2022-08-08T09:14:29.715Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1659950059, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2022-08-08T07:17:39.588Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(1659943048, 1),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1659943048, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2022-08-08T07:17:39.601Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2022-08-08T07:17:41.049Z")
},
"members" : [
{
"_id" : 0,
"name" : "ppgroup-mongo-redis01:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 7109,
"optime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-08-08T09:14:29Z"),
"lastAppliedWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastDurableWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1659943059, 1),
"electionDate" : ISODate("2022-08-08T07:17:39Z"),
"configVersion" : 8,
"configTerm" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "ppgroup-mongo-redis03:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 7022,
"optime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-08-08T09:14:29Z"),
"optimeDurableDate" : ISODate("2022-08-08T09:14:29Z"),
"lastAppliedWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastDurableWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastHeartbeat" : ISODate("2022-08-08T09:14:30.872Z"),
"lastHeartbeatRecv" : ISODate("2022-08-08T09:14:30.882Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "ppgroup-mongo-redis01:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 8,
"configTerm" : 1
},
{
"_id" : 3,
"name" : "ppgroup-mongo-redis02:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 4214,
"optime" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1659950069, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-08-08T09:14:29Z"),
"optimeDurableDate" : ISODate("2022-08-08T09:14:29Z"),
"lastAppliedWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastDurableWallTime" : ISODate("2022-08-08T09:14:29.715Z"),
"lastHeartbeat" : ISODate("2022-08-08T09:14:30.872Z"),
"lastHeartbeatRecv" : ISODate("2022-08-08T09:14:29.876Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "ppgroup-mongo-redis03:27017",
"syncSourceId" : 2,
"infoMessage" : "",
"configVersion" : 8,
"configTerm" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1659950069, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1659950069, 1)
5.测试数据同步
主库创建数据
use testdb
db.test1231.insert({"name":"test repl"});
从库查看数据
rs.secondaryOk();
db.test1231.find();
{ "_id" : ObjectId("62f0cc490a72461ed9866f18"), "name" : "test repl" }
从库可以正常同步数据