您好,登录后才能下订单哦!
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数据库的内容是不会被从节点复制的。
如果有不想被从节点复制的文档,可以将它放在本地数据库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
1 三个节点添加配置文件
[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",共同学习,共同成长!!!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。