MongoDB复制集
什么是MongoDB复制集?
复制集是由一组拥有相同数据集的mongodb实例所组成的集群,在多台服务器之间同步数据,(差不多跟MySQL的主从复制一个概念)
复制集的优点:
- 数据安全性更高,灾难恢复
- 数据可用性大,无需停机维护(比如备份、索引重建、故障转移)
- 读缩放(额外的副本读取),副本集对应用程序是透明的
MongoDB的复制集由多个节点构成(至少两个节点),其中一个是主节点,负责处理客户端的请求,其余的都是从节点,负责复制主节点上的数据
MongoDB一般由一主一从或者一主多从的方式搭配,主节点记录所有操作到oplog上,从节点再定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,保证和主节点的数据保持一致
复制集的选举原理(如下图)

节点类型分为三种:
标准节点(host):存储数据,可能被选为活跃(primary)节点,有选举权
被动节点(passive):被动节点有完整副本,不可能成为活跃节点,有选举权
仲裁节点(arbiter):负责选举,不存储数据,不能充当主从节点
选举的规则:
1.只有标准节点才会被选举为活跃节点(passive),有选举权,被动节点有完整副本,但是不能被选举为活跃节点,有选举权,仲裁节点不会复制数据,不可能被选举成为活跃节点,只有选举权
2.标准节点和被动节点的区别:priority的值高的是标准节点,低的是被动节点
3.选举最后得票高的人获胜,priority的优先权为0~1000之间,相当于额外增加这么多票
一、MongoDB复制集搭建
★准备工作★
一共需要3台服务器
Primary:192.168.31.101
Secondary1:192.168.31.102
Secondary2:192.168.31.103
安装包:mongodb-linux-x86_64-rhel70-4.0.28.tgz
三台服务器安装mongodb
1.三台服务器安装mongodb
yum -y install openssl-devel
tar zxf mongodb-linux-x86_64-rhel70-4.0.28.tgz
mv mongodb-linux-x86_64-rhel70-4.0.28 /mongodb
mkdir -p /mongodb/{data,logs,run,conf}
touch /mongodb/logs/mongo.log
2.配置三台mongodb服务配置文件并启动服务
Primary(192.168.31.101)、Secondary1(192.168.31.102)、Secondary2(192.168.31.103):
replSet参数指定集群名字
vim /mongodb/conf/mongo.conf
---------------------------------
port=27017
bind_ip=0.0.0.0
dbpath=/mongodb/data
logpath=/mongodb/logs/mongo.log
logappend=true
pidfilepath=/mongodb/run/mongo.pid
fork=true
maxConns=5000
storageEngine=wiredTiger
replSet=kgcrs
三台mongodb启动服务
/mongodb/bin/mongod -f /mongodb/conf/mongo.conf
验证启动是否成功:
netstat -anptu |grep mongo
ps -aux |grep mongod |grep -v grep
配置复制集
创建和查看集群
> cfg={"_id":"kgcrs","members":[{"_id":0,"host":"192.168.31.101:27017"},{"_id":1,"host":"192.168.31.102:27017"},{"_id":2,"host":"192.168.31.103:27017"}]}
{
"_id" : "kgcrs",
"members" : [
{
"_id" : 0,
"host" : "192.168.31.101:27017"
},
{
"_id" : 1,
"host" : "192.168.31.102:27017"
},
{
"_id" : 2,
"host" : "192.168.31.103:27017"
}
]
}
> rs.initiate(cfg)
{ "ok" : 1 }
kgcrs:OTHER>
kgcrs:PRIMARY>
查看选举状态
kgcrs:PRIMARY> rs.isMaster()
{
"hosts" : [
"192.168.31.101:27017",
"192.168.31.102:27017",
"192.168.31.103:27017"
],
"setName" : "kgcrs",
"setVersion" : 1,
"ismaster" : true,
"secondary" : false,
"primary" : "192.168.31.101:27017",
"me" : "192.168.31.101:27017",
"electionId" : ObjectId("7fffffff0000000000000001"),
"lastWrite" : {
"opTime" : {
"ts" : Timestamp(1658147299, 1),
"t" : NumberLong(1)
},
"lastWriteDate" : ISODate("2022-07-18T12:28:19Z"),
"majorityOpTime" : {
"ts" : Timestamp(1658147299, 1),
"t" : NumberLong(1)
},
"majorityWriteDate" : ISODate("2022-07-18T12:28:19Z")
},
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2022-07-18T12:28:22.200Z"),
"logicalSessionTimeoutMinutes" : 30,
"minWireVersion" : 0,
"maxWireVersion" : 7,
"readOnly" : false,
"ok" : 1,
"operationTime" : Timestamp(1658147299, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1658147299, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
查看复制集状态信息
kgcrs:PRIMARY> rs.status()
{
"set" : "kgcrs",
"date" : ISODate("2022-07-18T12:30:01.753Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"appliedOpTime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1658147389, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2022-07-18T12:25:49.103Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1658147137, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2022-07-18T12:25:49.109Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2022-07-18T12:25:50.049Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.31.101:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1896,
"optime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-07-18T12:29:59Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1658147149, 1),
"electionDate" : ISODate("2022-07-18T12:25:49Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.31.102:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 263,
"optime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-07-18T12:29:59Z"),
"optimeDurableDate" : ISODate("2022-07-18T12:29:59Z"),
"lastHeartbeat" : ISODate("2022-07-18T12:30:01.474Z"),
"lastHeartbeatRecv" : ISODate("2022-07-18T12:30:00.497Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.31.101:27017",
"syncSourceHost" : "192.168.31.101:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.31.103:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 263,
"optime" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1658147399, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2022-07-18T12:29:59Z"),
"optimeDurableDate" : ISODate("2022-07-18T12:29:59Z"),
"lastHeartbeat" : ISODate("2022-07-18T12:30:01.474Z"),
"lastHeartbeatRecv" : ISODate("2022-07-18T12:30:00.470Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.31.101:27017",
"syncSourceHost" : "192.168.31.101:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1658147399, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1658147399, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
“stateStr” : "PRIMARY"表示该id服务器为主服务器,“stateStr” : "SECONDARY"表示该id的服务器为从服务器
health为1代表健康,0代表宕机,state为1代表主节点,为2代表从节点
添加和删除节点
添加节点
kgcrs:PRIMARY> rs.add("192.168.31.104:27017")
{ "ok" : 1 }
删除节点
kgcrs:PRIMARY> rs.remove("192.168.31.104:27017")
{ "ok" : 1 }
故障测试
停止Primary(192.168.31.101)的mongodb服务,登录mongodb查看群集状态(如下所示)
kgcrs:PRIMARY> rs.status()
{
"set" : "kgcrs",
"date" : ISODate("2022-07-18T12:42:40.784Z"),
"myState" : 1,
"term" : NumberLong(2),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"appliedOpTime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"durableOpTime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
}
},
"lastStableCheckpointTimestamp" : Timestamp(1658148109, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "stepUpRequestSkipDryRun",
"lastElectionDate" : ISODate("2022-07-18T12:41:53.324Z"),
"electionTerm" : NumberLong(2),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(1658148109, 1),
"t" : NumberLong(1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1658148109, 1),
"t" : NumberLong(1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"priorPrimaryMemberId" : 0,
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2022-07-18T12:41:53.331Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2022-07-18T12:41:54.378Z")
},
"electionParticipantMetrics" : {
"votedForCandidate" : true,
"electionTerm" : NumberLong(1),
"lastVoteDate" : ISODate("2022-07-18T12:25:49.101Z"),
"electionCandidateMemberId" : 0,
"voteReason" : "",
"lastAppliedOpTimeAtElection" : {
"ts" : Timestamp(1658147137, 1),
"t" : NumberLong(-1)
},
"maxAppliedOpTimeInSet" : {
"ts" : Timestamp(1658147137, 1),
"t" : NumberLong(-1)
},
"priorityAtElection" : 1
},
"members" : [
{
"_id" : 0,
"name" : "192.168.31.101:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2022-07-18T12:42:39.421Z"),
"lastHeartbeatRecv" : ISODate("2022-07-18T12:41:52.548Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "Error connecting to 192.168.31.101:27017 :: caused by :: Connection refused",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "192.168.31.102:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1034,
"optime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2022-07-18T12:42:33Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1658148113, 1),
"electionDate" : ISODate("2022-07-18T12:41:53Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "192.168.31.103:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1020,
"optime" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"optimeDurable" : {
"ts" : Timestamp(1658148153, 1),
"t" : NumberLong(2)
},
"optimeDate" : ISODate("2022-07-18T12:42:33Z"),
"optimeDurableDate" : ISODate("2022-07-18T12:42:33Z"),
"lastHeartbeat" : ISODate("2022-07-18T12:42:39.400Z"),
"lastHeartbeatRecv" : ISODate("2022-07-18T12:42:39.697Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.31.102:27017",
"syncSourceHost" : "192.168.31.102:27017",
"syncSourceId" : 1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"operationTime" : Timestamp(1658148153, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1658148153, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
发现192.168.31.102:27017变成了主节点PRIMARY则说明成功!!!
二、复制集的认证
认证方式:
通过配置auth参数来开启权限认证,但这种认证方式只适合单机节点,当我们使用复制集时应该怎么开启权限认证来保证复制集的
单点认证
vim /mongodb/conf/mongo.conf
---------------------------------------------
auth=true
群集keyFile认证
1.修改配置文件
vim /usr/local/mongodb/bin/mongodb1.conf
----------------------------------------
clusterAuthMode=keyFile
keyFile=/mongodb/run/mongo-keyfile
2.创建kgcrskey文件加入内容
touch /mongodb/run/mongo-keyfile
3.配置keyFile文件再给权限
文件中的具体内容其实就是一行字符串,但复制集对keyFile文件有所要求
内容:以base64编码集中中的字符进行编写,即字符串只能包含a-z、A-Z、+、/
长度不能超过1000字节
权限最多到600 ,权限至少 chmod 600 keyFile
openssl rand -base64 102 > /mongodb/run/mongo-keyfile
chmod 600 /mongodb/run/mongo-keyfile
注意:每个节点都要进行该操作