MongoDB日常运维-04副本集搭建
一:MongoDB常用命令汇总
二:MongoDB安装
三:MongoDB主从复制搭建
四:MongoDB副本集搭建
五:MongoDB副本集故障切换
六:MongoDB副本集搭建错误汇总
参考:
https://blog.csdn.net/qq_39329616/article/details/89409728
四:MongoDB副本集搭建
没有固定的主节点,集群会自动选举出一个主节点,当这个主节点不能正常工作时,又会另外选举出其他节点作为主节点。
副本集中总会有一个主节点和一个(多个)备份节点,当主节点出问题时,备份节点会提升为主节点。
在副本集中会有一个只参与投票选举、不复制数据的仲裁节点,用于当票数出现一致时来判决。官方推荐集群节点为奇数。
副本集工作原理
1.oplog(操作日志)
记录数据改变操作(更新插入),oplog是一个固定集合,位于每个复制节点的local的数据库里。
新操作会替换旧的操作,以保证oplog不会超过预设的大小,oplog中的每个文档都代表主节点上执行的一个操作。
2.数据同步
每个oplog都有时间戳,所有从节点都使用这个时间戳来追踪它们最后执行写操作的记录。
当某个从节点准备更新自己时,会做三件事:
首先,查看自己oplog里的最后一条时间戳;
其次,查询主节点oplog里所有大于此时间戳的文档;
最后,把那些文档应用到自己库里,并添加写操作文档到自己的oplog里。
3.复制状态和本地数据库
复制状态的文档记录在本地数据库local中。
如果有不想被从节点复制的文档,可以将它放在本地数据库local中。
4.阻塞复制
当主节点写入操作太快时,从节点的更新状态有可能跟不上。
为避免这种情况:
使主节点的oplog足够大
阻塞复制:在主节点使用getLastError命令加参数“w”来确保数据的同步性。w越大会导致写操作越慢。
5.心跳机制
心跳检测有助于发现故障进行自动选举和故障转移。默认情况下副本集成员每两分钟ping一下其他成员,来检测健康状态。
如果是某一从节点出现故障只会等待从节点重新上线,而如果主节点出现故障,则副本集开始选举,重新选出新的主节点,原主节点会降级为从节点。
6.选举机制
根据优先级和Bully算法(评判谁的数据最新)选举出主节点,在选举出主节点之前,整个集群服务是只读的,不能执行写操作。
非仲裁节点都会有优先级配置,范围为0~100,越大值越优先成为主节点,默认为1,如果是0则不能成为主节点。
拥有资格的从节点会向其他节点发出请求,而其他节点在收到选举提议后会判断三个条件:
1 副本集中是否有其他节点已经是主节点了
2 自己的数据是否比请求成为主节点的的那个节点上数据更新
3 副本集中其他节点的数据是否比请求成为主节点的那个节点数据更新
只要有一个条件成立,都会认为对方提议不可行。请求者只要收到任何一个节点返回不合适,都会退出选举。
选举机制会让优先级高的节点成为主节点,即使先选举出了优先级低的节点,也至少会短暂作为主节点运行一段时间。
副本集还会再之后继续发出选举,直到优先级最高的节点成为主节点。
7.数据回滚
在从节点成为主节点后,会认为其是副本集中的最新数据,对其他节点的操作都会回滚,即所有节点连接新的主节点重新同步。
这些节点会查看自己的oplog,找出新主节点中没有执行过的操作,然后请求操作文档,替换掉自己的异常样本。
副本集搭建
主库:192.168.2.222 cjcos
从库:192.168.2.187 rac1
仲裁:192.168.2.188 rac2
[root@cjcos conf]# pwd
/usr/local/mongodb/conf
[root@cjcos conf]# vim mongodb.conf
#集群名称
replSet=cjcmonset
2 启动数据库
[root@cjcos conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf
[root@rac1 conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf
[root@rac2 conf]# mongod --config /usr/local/mongodb/conf/mongodb.conf
3 配置副本集
3.1 配置主primary
> use admin
switched to db admin
> config={_id:"cjcmonset",members:
[{_id:0,host:"192.168.2.222:27017",priority:1},
{_id:1,host:"192.168.2.187:27017",priority:1},
{_id:2,host:"192.168.2.188:27017",priority:1,arbiterOnly:true}]}
{
"_id" : "cjcmonset",
"members" : [
{
"_id" : 0,
"host" : "192.168.2.222:27017",
"priority" : 1
},
{
"_id" : 1,
"host" : "192.168.2.187:27017",
"priority" : 1
},
{
"_id" : 2,
"host" : "192.168.2.188:27017",
"priority" : 1,
"arbiterOnly" : true
}
]
}
初始化配置
> rs.initiate(config)
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1584862345, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1584862345, 1)
}
查看集群配置
cjcmonset:PRIMARY> rs.config()
{
"_id" : "cjcmonset",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "192.168.2.222:27017",
"arbiterOnly" : false,
"buildindexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"Votes" : 1
},
{
"_id" : 1,
"host" : "192.168.2.187:27017",
"arbiterOnly" : false,
"buildindexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"Votes" : 1
},
{
"_id" : 2,
"host" : "192.168.2.188:27017",
"arbiterOnly" : true,
"buildindexes" : true,
"hidden" : false,
"priority" : 0,
"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("5e77148837ae69b4ab9b4870")
}
}
查看状态:
cjcmonset:PRIMARY> rs.status()
{
"set" : "cjcmonset",
"date" : ISODate("2020-03-22T07:34:18.866Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2020-03-22T07:34:16.862Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2020-03-22T07:34:16.862Z"),
"appliedOpTime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2020-03-22T07:34:16.862Z"),
"lastDurableWallTime" : ISODate("2020-03-22T07:34:16.862Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1584862416, 1),
"lastStableCheckpointTimestamp" : Timestamp(1584862416, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2020-03-22T07:32:35.618Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenopTimeAtElection" : {
"ts" : Timestamp(1584862345, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 1,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2020-03-22T07:32:36.851Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2020-03-22T07:32:37.889Z")
},
"members" : [
{
"_id" : 0,
"name" : "192.168.2.222:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 211,
"optime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-03-22T07:34:16Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "Could not find member to sync from",
"electionTime" : Timestamp(1584862355, 1),
"electionDate" : ISODate("2020-03-22T07:32:35Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.2.187:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 113,
"optime" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1584862456, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-03-22T07:34:16Z"),
"optimeDurableDate" : ISODate("2020-03-22T07:34:16Z"),
"lastHeartbeat" : ISODate("2020-03-22T07:34:17.751Z"),
"lastHeartbeatRecv" : ISODate("2020-03-22T07:34:18.157Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "192.168.2.222:27017",
"syncSourceHost" : "192.168.2.222:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "192.168.2.188:27017",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 113,
"lastHeartbeat" : ISODate("2020-03-22T07:34:17.750Z"),
"lastHeartbeatRecv" : ISODate("2020-03-22T07:34:17.948Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1584862456, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1584862456, 1)
}
数据同步测试
主库创建测试数据库cjcdb,创建测试表t01并插入数据
cjcmonset:PRIMARY> use cjcdb
switched to db cjcdb
cjcmonset:PRIMARY> show collections
cjcmonset:PRIMARY> db.createCollection("t01")
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1584880911, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1584880911, 1)
}
cjcmonset:PRIMARY> db.t01.insert({"tname":"cjc"})
WriteResult({ "nInserted" : 1 })
cjcmonset:PRIMARY> db.t01.find()
{ "_id" : ObjectId("5e775d3d1cf1e6a03a41253c"), "tname" : "cjc" }
查看数据库
cjcmonset:PRIMARY> show dbs
admin 0.000GB
cjcdb 0.000GB
config 0.000GB
local 0.000GB
从库查看数据
187从库:
cjcmonset:SECONDARY> show dbs
2020-03-22T20:43:47.784+0800 E QUERY [js] uncaught exception: Error: listDatabases Failed:{
"operationTime" : Timestamp(1584881019, 1),
"ok" : 0,
"errmsg" : "not master and slaveOk=false",
"code" : 13435,
"codeName" : " NotMasterNoSlaveOk",
"$clusterTime" : {
"clusterTime" : Timestamp(1584881019, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs/<@src/mongo/shell/mongo.js:135:19
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:87:12
shellHelper.show@src/mongo/shell/utils.js:906:13
shellHelper@src/mongo/shell/utils.js:790:15
@(shellhelp2):1:1
cjcmonset:SECONDARY> rs.slaveOk()
cjcmonset:SECONDARY> show dbs
admin 0.000GB
cjcdb 0.000GB
config 0.000GB
local 0.000GB
cjcmonset:SECONDARY> use cjcdb
switched to db cjcdb
cjcmonset:SECONDARY> db.t01.find()
{ "_id" : ObjectId("5e775d3d1cf1e6a03a41253c"), "tname" : "cjc" }
主库日志如下:
2020-03-22T20:41:51.247+0800 I STORAGE [conn1] createCollection: cjcdb.t01 with generated UUID: 7dd8d050-ac8b-4c6d-b46d-43a8c54b74a2 and options: {}
2020-03-22T20:41:51.541+0800 I INDEX [conn1] index build: done building index _id_ on ns cjcdb.t01
2020-03-22T20:41:51.542+0800 I COMMAND [conn1] command cjcdb.t01 appName: "MongoDB Shell" command: create { create: "t01", lsid: { id: UUID("3383ae30-677c-4fce-b244-162342b1a28e") }, $clusterTime: { clusterTime: Timestamp(1584880879, 1), signature: { hash: BinData(0, 0000000000000000000000000000000000000000), keyId: 0 } }, $db: "cjcdb" } numYields:0 reslen:163 locks:{ ParallelBatchWriterMode: { acquireCount: { r: 2 } }, ReplicationStateTransition: { acquireCount: { w: 2 } }, Global: { acquireCount: { w: 2 } }, Database: { acquireCount: { w: 1, W: 1 } }, Collection: { acquireCount: { r: 2, W: 1 } }, Mutex: { acquireCount: { r: 1 } } } flowControl:{ acquireCount: 2 } storage:{} protocol:op_msg 294ms
2020-03-22T20:42:37.293+0800 I SHARDING [conn1] Marking collection cjcdb.t01 as collection version: <unsharded>
188仲裁节点
而进入仲裁者节点时,会发现不能读写,因为他只负责投票选举。
cjcmonset:ARBITER> rs.slaveOk()
cjcmonset:ARBITER> show dbs
local 0.000GB
欢迎关注我的微信公众号"IT小Chen",共同学习,共同成长!!!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。