centos7.6部署mongodb復(fù)制集RS(ReplicationSet),通過多實例實現(xiàn),即一臺服務(wù)器部署4個實例,通過不同的端口區(qū)分。
MongoDB中的復(fù)制集(也被稱為副本)是一組維護相同數(shù)據(jù)集的mongod進程。副本集提供冗余性及和高可用,是所有生產(chǎn)部署的基礎(chǔ)。簡單來說,復(fù)制集有多臺MongoDB組成的一個集群,集群中有一個主節(jié)點(Primary)和N個副本節(jié)點(Secondary)等,它們有相同的數(shù)據(jù)庫,假如主MongoDB服務(wù)器或者MongoDB實例Down機之后,其它的副本服務(wù)器可以繼續(xù)提供服務(wù),實現(xiàn)數(shù)據(jù)的高可用及可靠性。
1 mongodb復(fù)制集架構(gòu)
1.1 角色介紹:
術(shù)語 類型 描述
Primary 主節(jié)點 負責(zé)整個集群的讀寫操作,包含了所有改變操作的日志
Secondary 備節(jié)點 同步主服務(wù)器所有的數(shù)據(jù),負責(zé)集群的讀取請求,主服務(wù)器宕機可以稱為主節(jié)點
Arbiter 仲裁者 在主節(jié)點宕機后只進行投票,不參與選舉,不同步主節(jié)點數(shù)據(jù)
1.2 mongodb的復(fù)制集架構(gòu)主要分為兩種,普通復(fù)制集和選主復(fù)制集。
1、普通復(fù)制集架構(gòu):

image.png
主節(jié)點故障后,復(fù)制集變化過程

image.png
2、選主復(fù)制集架構(gòu)(仲裁節(jié)點架構(gòu))

image.png
主節(jié)點故障后,復(fù)制集變化過程

image.png
1.3 基本原理
復(fù)制集基本架構(gòu)為1主2從或1主1從1Arbiter 。而且mongodb復(fù)制集自帶互相監(jiān)控投票機制,其內(nèi)部算法為【MongoD(Raft)】和【Paxos(mysql MGR )】算法基本相同。
如果發(fā)生主庫宕機,復(fù)制集內(nèi)部會根據(jù)Raft算法進行投票選舉,選擇一個新的主庫替代原有主庫對外提供服務(wù)。同時復(fù)制集會自動通知客戶端程序,主庫已經(jīng)發(fā)生切換了,應(yīng)用就會連接到新的主庫。
2 復(fù)制集架構(gòu)規(guī)劃
可以使用3個節(jié)點或多實例實現(xiàn)。本案例通過多實例實現(xiàn)。
2.1 多實例規(guī)劃
節(jié)點:172.21.209.123
端口:28017-28020(實現(xiàn)多實例)
2.2 多實例目錄
登陸到mongod用戶并創(chuàng)建多實例目錄
[root@mysql-master ~]# su - mongod
[mongod@mysql-master /data]$ mkdir /data/mongodb/mult-mongodb
2.3 創(chuàng)建多實例數(shù)據(jù)目錄
[mongod@mysql-master mult-mongodb]$ for path in {28017..28020}
> do
> mkdir -vp /data/mongodb/mult-mongodb/$path/{data,conf,log}
> done
mkdir: created directory ‘/data/mongodb/mult-mongodb/28017’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28017/data’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28017/conf’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28017/log’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28018’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28018/data’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28018/conf’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28018/log’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28019’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28019/data’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28019/conf’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28019/log’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28020’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28020/data’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28020/conf’
mkdir: created directory ‘/data/mongodb/mult-mongodb/28020/log’
查看創(chuàng)建的多實例目錄,通過不同的端口區(qū)分
[mongod@mysql-master mult-mongodb]$ ll
total 0
drwxrwxr-x 5 mongod mongod 41 Sep 24 04:52 28017
drwxrwxr-x 5 mongod mongod 41 Sep 24 04:52 28018
drwxrwxr-x 5 mongod mongod 41 Sep 24 04:52 28019
drwxrwxr-x 5 mongod mongod 41 Sep 24 04:52 28020
2.4 多實例配置文件
1、配置文件路徑
/data/mongodb/mult-mongodb/28017/conf/mongod.conf
/data/mongodb/mult-mongodb/28018/conf/mongod.conf
/data/mongodb/mult-mongodb/28019/conf/mongod.conf
/data/mongodb/mult-mongodb/28020/conf/mongod.conf
2、配置文件內(nèi)容
cat >/data/mongodb/mult-mongodb/28017/conf/mongod.conf <<EOF
systemLog:
destination: file
path: /data/mongodb/mult-mongodb/28017/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /data/mongodb/mult-mongodb/28017/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
bindIp: 172.21.209.123,127.0.0.1
port: 28017
replication:
oplogSizeMB: 2048
replSetName: myReplSet
EOF
3、復(fù)制配置 文件到其他實例的conf目錄下,并修改端口
[mongod@mysql-master conf]$ cp /data/mongodb/mult-mongodb/28017/conf/mongod.conf /data/mongodb/mult-mongodb/28018/conf/
[mongod@mysql-master conf]$ cp /data/mongodb/mult-mongodb/28017/conf/mongod.conf /data/mongodb/mult-mongodb/28019/conf/
[mongod@mysql-master conf]$ cp /data/mongodb/mult-mongodb/28017/conf/mongod.conf /data/mongodb/mult-mongodb/28020/conf/
修改配置文件
[mongod@mysql-master conf]$ sed 's#28017#28018#g' /data/mongodb/mult-mongodb/28018/conf/mongod.conf -i
[mongod@mysql-master conf]$ sed 's#28017#28019#g' /data/mongodb/mult-mongodb/28019/conf/mongod.conf -i
[mongod@mysql-master conf]$ sed 's#28017#28020#g' /data/mongodb/mult-mongodb/28020/conf/mongod.conf -i
2.5 啟動多實例
mongod -f /data/mongodb/mult-mongodb/28017/conf/mongod.conf
mongod -f /data/mongodb/mult-mongodb/28018/conf/mongod.conf
mongod -f /data/mongodb/mult-mongodb/28019/conf/mongod.conf
mongod -f /data/mongodb/mult-mongodb/28020/conf/mongod.conf
啟動過程:
[mongod@mysql-master conf]$ mongod -f /data/mongodb/mult-mongodb/28017/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 29035
child process started successfully, parent exiting
[mongod@mysql-master conf]$ mongod -f /data/mongodb/mult-mongodb/28018/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 29073
child process started successfully, parent exiting
[mongod@mysql-master conf]$ mongod -f /data/mongodb/mult-mongodb/28019/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 29111
child process started successfully, parent exiting
[mongod@mysql-master conf]$ mongod -f /data/mongodb/mult-mongodb/28020/conf/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 29149
child process started successfully, parent exiting
2.6 查看進程和端口
[mongod@mysql-master conf]$ ps -ef|grep mongodb
[mongod@mysql-master conf]$ netstat -lntp|grep 280
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
tcp 0 0 172.21.209.123:28017 0.0.0.0:* LISTEN 29035/mongod
tcp 0 0 127.0.0.1:28017 0.0.0.0:* LISTEN 29035/mongod
tcp 0 0 172.21.209.123:28018 0.0.0.0:* LISTEN 29073/mongod
tcp 0 0 127.0.0.1:28018 0.0.0.0:* LISTEN 29073/mongod
tcp 0 0 172.21.209.123:28019 0.0.0.0:* LISTEN 29111/mongod
tcp 0 0 127.0.0.1:28019 0.0.0.0:* LISTEN 29111/mongod
tcp 0 0 172.21.209.123:28020 0.0.0.0:* LISTEN 29149/mongod
tcp 0 0 127.0.0.1:28020 0.0.0.0:* LISTEN 29149/mongod
3 配置復(fù)制集
3.1 配置普通復(fù)制集【1主2從】
1、登陸到mongodb數(shù)據(jù)庫
[mongod@mysql-master data]$ mongo --port 28017 admin
2、配置mongodb復(fù)制集
config = {_id: 'myReplSet', members: [
{_id: 0, host: '172.21.209.123:28017'},
{_id: 1, host: '172.21.209.123:28018'},
{_id: 2, host: '172.21.209.123:28019'}]
}
rs.initiate(config)
注:
admin為驗證庫。
集群過程中會出現(xiàn)兩種角色PRIMARY和SECONDARY,為配置成功。
myReplSet:SECONDARY>
myReplSet:PRIMARY>
3、查看復(fù)制集集群的狀態(tài)
myReplSet:PRIMARY> rs.status()
3.2、配置選擇復(fù)制集【1主1從1個arbiter】
[mongod@mysql-master data]$ mongo --port 28017 admin
config = {_id: 'myReplSet', members: [
{_id: 0, host: '172.21.209.123:28017'},
{_id: 1, host: '172.21.209.123:28018'},
{_id: 2, host: '172.21.209.123:28019',"arbiterOnly":true}]
}
rs.initiate(config)
注:myReplSet要和配置文件中的復(fù)制集模塊一致。
arbiterOnly設(shè)置為true.
3.3、復(fù)制集常用管理操作
rs.status(); //查看復(fù)制集狀態(tài)
rs.isMaster(); // 查看當(dāng)前是否為主節(jié)點
rs.conf(); //查看復(fù)制集配置信息
1、查看復(fù)制集狀態(tài)
myReplSet:PRIMARY> rs.status()
{
"set" : "myReplSet",
"date" : ISODate("2021-09-24T09:35:30.813Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2021-09-24T09:35:27.923Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2021-09-24T09:35:27.923Z"),
"appliedOpTime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2021-09-24T09:35:27.923Z"),
"lastDurableWallTime" : ISODate("2021-09-24T09:35:27.923Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1632476117, 1),
"lastStableCheckpointTimestamp" : Timestamp(1632476117, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2021-09-24T09:21:17.879Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1632475267, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2021-09-24T09:21:17.905Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2021-09-24T09:21:18.701Z")
},
"members" : [
{
"_id" : 0,
"name" : "172.21.209.123:28017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1645,
"optime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-09-24T09:35:27Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1632475277, 1),
"electionDate" : ISODate("2021-09-24T09:21:17Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "172.21.209.123:28018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 863,
"optime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-09-24T09:35:27Z"),
"optimeDurableDate" : ISODate("2021-09-24T09:35:27Z"),
"lastHeartbeat" : ISODate("2021-09-24T09:35:29.897Z"),
"lastHeartbeatRecv" : ISODate("2021-09-24T09:35:29.171Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "172.21.209.123:28017",
"syncSourceHost" : "172.21.209.123:28017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.21.209.123:28019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 863,
"optime" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1632476127, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-09-24T09:35:27Z"),
"optimeDurableDate" : ISODate("2021-09-24T09:35:27Z"),
"lastHeartbeat" : ISODate("2021-09-24T09:35:29.896Z"),
"lastHeartbeatRecv" : ISODate("2021-09-24T09:35:30.673Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "172.21.209.123:28017",
"syncSourceHost" : "172.21.209.123:28017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1632476127, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1632476127, 1)
}
myReplSet:PRIMARY>
2、查看當(dāng)前節(jié)點是否為主節(jié)點
myReplSet:PRIMARY> rs.isMaster()
{
"hosts" : [
"172.21.209.123:28017",
"172.21.209.123:28018",
"172.21.209.123:28019"
],
"setName" : "myReplSet",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "172.21.209.123:28017",
"me" : "172.21.209.123:28017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1632476167, 1),
"t" : NumberLong(1)
},
"lastWriteDate" : ISODate("2021-09-24T09:36:07Z"),
"majorityOpTime" : {
"ts" : Timestamp(1632476167, 1),
"t" : NumberLong(1)
},
"majorityWriteDate" : ISODate("2021-09-24T09:36:07Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2021-09-24T09:36:10.629Z"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 6,
"minWireVersion" : 0,
"maxWireVersion" : 8,
"readOnly" : false,
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1632476167, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1632476167, 1)
}
myReplSet:PRIMARY>
3、查看復(fù)制集配置信息
myReplSet:PRIMARY> rs.conf()
{
"_id" : "myReplSet",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "172.21.209.123:28017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "172.21.209.123:28018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "172.21.209.123:28019",
"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("614d98833680adfa6bcd2c0e")
}
}
myReplSet:PRIMARY>
4 復(fù)制集節(jié)點的添加和刪除
1、添加刪除常用操作
rs.remove("節(jié)點ip:port"); // 刪除一個節(jié)點
rs.add("節(jié)點ip:port"); // 新增從節(jié)點
rs.addArb("節(jié)點ip:port"); // 新增仲裁節(jié)點
2、案例操作
連接到主節(jié)點
[mongod@mysql-master data]$ mongo --port 28017 admin
2.1 添加仲裁節(jié)點
myReplSet:PRIMARY> rs.addArb("172.21.209.123:28020")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1632476954, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1632476954, 1)
}
添加后查看狀態(tài):myReplSet:PRIMARY> rs.isMaster()
2.2 刪除一個節(jié)點
myReplSet:PRIMARY> rs.remove("172.21.209.123:28019");
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1632477110, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1632477110, 1)
}
刪除后查看狀態(tài):myReplSet:PRIMARY> rs.isMaster()
2.3 新增加從節(jié)點
myReplSet:PRIMARY> rs.add("1172.21.209.123:28019")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1632477186, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1632477186, 1)
}
新增后查看狀態(tài):myReplSet:PRIMARY> rs.isMaster()
5 復(fù)制集的特殊節(jié)點
5.1 介紹和架構(gòu)
- arbiter節(jié)點:主要負責(zé)選主過程投票,但不存儲任何數(shù)據(jù),也不向客戶端提供任何服務(wù)
- hidden節(jié)點:隱藏節(jié)點,不參與選主,也不向客戶端提供任何服務(wù)。
- delay節(jié)點:延時節(jié)點,數(shù)據(jù)落后于主庫一段時間,因為數(shù)據(jù)是延時的,也不應(yīng)該提供服務(wù)或參與選主,所以通常會配合hidden(隱藏)
一般情況下會將delay+hidden一起配置使用

image.png

image.png
5.2 配置延時節(jié)點(組合使用:delay+hidden)
1、配置延時
cfg=rs.conf()
cfg.members[1].priority=0
cfg.members[1].hidden=true
cfg.members[1].slaveDelay=120
rs.reconfig(cfg)
2、恢復(fù)延時配置
cfg=rs.conf()
cfg.members[1].priority=1
cfg.members[1].hidden=false
cfg.members[1].slaveDelay=0
rs.reconfig(cfg)
3、配置成功后,通過以下命令查詢配置后的屬性
rs.conf();
注:通過rs.status()可以查看到members[1]是一個數(shù)組,下標從0開始,選擇需要配置的節(jié)點,members[1]表示第三個節(jié)點。
6 復(fù)制集其他命令
1、查看副本集的配置信息
myReplSet:PRIMARY> rs.conf()
2、查看副本集各成員的狀態(tài)
myReplSet:PRIMARY> rs.status()
3、副本集角色切換(不要人為隨便操作)
myReplSet:PRIMARY> rs.stepDown()
注:
myReplSet:PRIMARY> rs.freeze(300) //鎖定從,使其不會轉(zhuǎn)變成主庫
freeze()和stepDown單位都是秒。
4、設(shè)置副本節(jié)點可讀:在副本節(jié)點執(zhí)行
登陸從節(jié)點
[mongod@mysql-master data]$ mongo --port 28018 admin
myReplSet:SECONDARY> rs.slaveOk()
eg:
myReplSet:SECONDARY> use student;
switched to db student
myReplSet:SECONDARY> db.createCollection('a')
{
"operationTime" : Timestamp(1632478227, 1),
"ok" : 0,
"errmsg" : "not master",
"code" : 10107,
"codeName" : "NotWritablePrimary",
"$clusterTime" : {
"clusterTime" : Timestamp(1632478227, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
5、查看副本節(jié)點(監(jiān)控主從延時)
myReplSet:SECONDARY> rs.printSlaveReplicationInfo()
WARNING: printSlaveReplicationInfo is deprecated and may be removed in the next major release. Please use printSecondaryReplicationInfo instead.
source: 172.21.209.123:28018
syncedTo: Fri Sep 24 2021 06:13:08 GMT-0400 (EDT)
0 secs (0 hrs) behind the primary
source: 1172.21.209.123:28019
syncedTo: Wed Dec 31 1969 19:00:00 GMT-0500 (EST)
1632478388 secs (453466.22 hrs) behind the primary
至此:mongodb的復(fù)制集部署完成,通過多實例實現(xiàn)部署。