Principle of Copy Set
The role of replicated sets
Mainly in order to achieve mongodb
service, there is a master-slave relationship between the replica sets
- When data is written, the data is quickly copied to other nodes
- When the master node fails, a new node is automatically selected to replace
redis
on the above characteristics, if we understand 061aec02c3217c, we can quickly think of sentinel mode
In addition to the above data synchronization and
failed node replacement, the replication set also has the following functions
Data distribution: distribute data to different areas to reduce read delay
For example, the company has data centers in Beijing, Shanghai, and Guangzhou, but only in Beijing is a writeable center that can distribute data in different places, improving the reading efficiency of users in Shanghai and Guangzhou.
- Read and write separation
- Remote disaster recovery: Quickly switch to a remote location when the data center fails.
The structure of the replica set
The structure of the replica set is basically similar to the master-slave mode of other middleware.
A typical replica set consists of 3 or more nodes with voting:
- Master node: There is only one, responsible for writing and reading data, and voting during elections.
- Slave nodes: at least two, responsible for data reading and election voting.
data replication principle
- When the data ( master node ) is modified ( deletes, and changes ), its operations on the data will be recorded in a
oplog
file. - The slave node continuously obtains the newly added
oplog
in the master node by opening atailable
cursor on the master node and continuously reproduces these operations on its own node to achieve consistency with the data on the master node.
Master Node Election
- Nodes with voting rights send heartbeats to each other in pairs.
- When 5 heartbeats are not received, it is judged that the node is disconnected.
- If the master node loses connection, the slave node will elect a new master node, but the lost slave node will not participate in the election.
- The election is implemented based on the RAFT consensus algorithm. The necessary condition for a successful election is that most of the voting nodes survive.
- There can be up to 50 nodes in the replication set, but up to 7 have voting rights.
- The node elected as the master node must be able to establish connections with most nodes, have a relatively new
oplog
, and a relatively high priority (if there is one in the configuration)
Build a replica set
The following is to create a copy set of linux
mongodb
Create three directories
mkdir -p /data/mongodb/db{1,2,3}
Configuration file
#节点1
systemLog:
destination: file
path: /data/mongodb/db1/mongod.log #日志路径
logAppend: true
storage:
dbPath: /data/mongodb/db1 #数据文件
net:
bindIp: 0.0.0.0 #在所有网卡监听,为了外网访问
port: 28017
replication: #复制集,没有的话就是一个单节点
replSetName: rs0 #复制集名字
processManagement:
fork: true #把进程作为独立的后台进程进程
#节点2
systemLog:
destination: file
path: /data/mongodb/db2/mongod.log #日志路径
logAppend: true
storage:
dbPath: /data/mongodb/db2 #数据文件
net:
bindIp: 0.0.0.0 #在所有网卡监听,为了外网访问
port: 28018
replication: #复制集,没有的话就是一个单节点
replSetName: rs0 #复制集名字
processManagement:
fork: true #把进程作为独立的后台进程进程
#节点3
systemLog:
destination: file
path: /data/mongodb/db3/mongod.log #日志路径
logAppend: true
storage:
dbPath: /data/mongodb/db3 #数据文件
net:
bindIp: 0.0.0.0 #在所有网卡监听,为了外网访问
port: 28019
replication: #复制集,没有的话就是一个单节点
replSetName: rs0 #复制集名字
processManagement:
fork: true #把进程作为独立的后台进程进程
Start process
mongod -f db1/mongod.conf
mongod -f db2/mongod.conf
mongod -f db3/mongod.conf
Configure replication set
Enter the master node
mongo --port 28017
Set up the master node
rs.initiate()
{ "info2" : "no configuration specified. Using a default configuration for the set", "me" : "supman:28017", "ok" : 1 }
View node status
rs.status()
{ "set" : "rs0", "date" : ISODate("2021-11-30T15:33:30.616Z"), "myState" : 1, "term" : NumberLong(1), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 1, "writeMajorityCount" : 1, "votingMembersCount" : 1, "writableVotingMembersCount" : 1, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1638286404, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2021-11-30T15:33:24.656Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1638286404, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2021-11-30T15:33:24.656Z"), "appliedOpTime" : { "ts" : Timestamp(1638286404, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1638286404, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2021-11-30T15:33:24.656Z"), "lastDurableWallTime" : ISODate("2021-11-30T15:33:24.656Z") }, "lastStableRecoveryTimestamp" : Timestamp(1638286364, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2021-11-30T15:27:54.614Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1638286074, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 1, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "newTermStartDate" : ISODate("2021-11-30T15:27:54.637Z"), "wMajorityWriteAvailabilityDate" : ISODate("2021-11-30T15:27:54.660Z") }, "members" : [ { "_id" : 0, "name" : "supman:28017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1227, "optime" : { "ts" : Timestamp(1638286404, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-11-30T15:33:24Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1638286074, 2), "electionDate" : ISODate("2021-11-30T15:27:54Z"), "configVersion" : 1, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1638286404, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1638286404, 1) }
Find the members.name
field in the status information
"name" : "supman:28017"
Add slave node
rs.add("supman:28018")
{ "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1638286626, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1638286626, 1) }
rs.add("supman:28019")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1638286660, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1638286660, 1)
}
Check status again
{ "set" : "rs0", "date" : ISODate("2021-11-30T15:44:29.903Z"), "myState" : 1, "term" : NumberLong(1), "syncSourceHost" : "", "syncSourceId" : -1, "heartbeatIntervalMillis" : NumberLong(2000), "majorityVoteCount" : 2, "writeMajorityCount" : 2, "votingMembersCount" : 3, "writableVotingMembersCount" : 3, "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "lastCommittedWallTime" : ISODate("2021-11-30T15:44:24.673Z"), "readConcernMajorityOpTime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "readConcernMajorityWallTime" : ISODate("2021-11-30T15:44:24.673Z"), "appliedOpTime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "lastAppliedWallTime" : ISODate("2021-11-30T15:44:24.673Z"), "lastDurableWallTime" : ISODate("2021-11-30T15:44:24.673Z") }, "lastStableRecoveryTimestamp" : Timestamp(1638287034, 1), "electionCandidateMetrics" : { "lastElectionReason" : "electionTimeout", "lastElectionDate" : ISODate("2021-11-30T15:27:54.614Z"), "electionTerm" : NumberLong(1), "lastCommittedOpTimeAtElection" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "lastSeenOpTimeAtElection" : { "ts" : Timestamp(1638286074, 1), "t" : NumberLong(-1) }, "numVotesNeeded" : 1, "priorityAtElection" : 1, "electionTimeoutMillis" : NumberLong(10000), "newTermStartDate" : ISODate("2021-11-30T15:27:54.637Z"), "wMajorityWriteAvailabilityDate" : ISODate("2021-11-30T15:27:54.660Z") }, "members" : [ { "_id" : 0, "name" : "supman:28017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 1886, "optime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-11-30T15:44:24Z"), "syncSourceHost" : "", "syncSourceId" : -1, "infoMessage" : "", "electionTime" : Timestamp(1638286074, 2), "electionDate" : ISODate("2021-11-30T15:27:54Z"), "configVersion" : 3, "configTerm" : 1, "self" : true, "lastHeartbeatMessage" : "" }, { "_id" : 1, "name" : "supman:28018", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 442, "optime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-11-30T15:44:24Z"), "optimeDurableDate" : ISODate("2021-11-30T15:44:24Z"), "lastHeartbeat" : ISODate("2021-11-30T15:44:28.545Z"), "lastHeartbeatRecv" : ISODate("2021-11-30T15:44:28.566Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "supman:28017", "syncSourceId" : 0, "infoMessage" : "", "configVersion" : 3, "configTerm" : 1 }, { "_id" : 2, "name" : "supman:28019", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 409, "optime" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1638287064, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2021-11-30T15:44:24Z"), "optimeDurableDate" : ISODate("2021-11-30T15:44:24Z"), "lastHeartbeat" : ISODate("2021-11-30T15:44:28.565Z"), "lastHeartbeatRecv" : ISODate("2021-11-30T15:44:29.316Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "", "syncSourceHost" : "supman:28018", "syncSourceId" : 1, "infoMessage" : "", "configVersion" : 3, "configTerm" : 1 } ], "ok" : 1, "$clusterTime" : { "clusterTime" : Timestamp(1638287064, 1), "signature" : { "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="), "keyId" : NumberLong(0) } }, "operationTime" : Timestamp(1638287064, 1) }
Configure readable on the slave node
Enter slave node
mongo --port 28018
mongo --port 28019
Set the slave node to be readable
rs.slaveOk()
- Finally, add a user to the master node, create a database and collection, after inserting the data, you can also view the data in the slave node
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。