MongoDB 维护Replica Set
本文内容纲要:
在每个MongoDB(版本3.2.9)Instance中,都有一个本地数据库(local),用于存储Replication进程的信息和本地数据。local数据库的特性是:位于local数据库中的数据和集合不会被Replication进程复制到其他MongoDBinstance上。如果实例上有些collection和data不计划被复制到其他MongoDBInstance,可以将这些collection和data存储在local数据库中。
MongoDBshell提供一个全局变量rs,是数据库命令的包装器(wrapper),用于维护ReplicaSet。
一,ReplicaSet的配置
1,查看ReplicaSet的配置信息
MongoDB将ReplicaSet的配置信息存储在local.system.replset集合中,在同一个ReplicaSet中所有成员local.system.replset是相同的,不能直接修改该集合,必须通过rs.initiate()来初始化,通过rs.reconfig()来重新配置,对ReplicaSet增加或删除成员都会相应的修改ReplicaSet的配置信息。
rs.config()
uselocal
db.system.replset.find()
配置信息重要信息主要有两部分:ReplicaSet的id值和member数组。
{
_id:"replicasetname",
members:[
{
_id:<int>,
host:"host:port",
arbiterOnly:<boolean>,
buildIndexes:<boolean>,
hidden:<boolean>,
priority:<number>,
slaveDelay:<int>,
votes:<number>
},
...
],
...
}
成员的配置文档:
priority:表示一个成员被选举为Primary节点的优先级,默认值是1,取值范围是从0到100,将priority设置为0有特殊含义:Priority为0的成员永远不能成为Primary节点。ReplicaSet中,Priority最高的成员,会优先被选举为Primary节点,只要其满足条件。
hidden:将成员配置为隐藏成员,要求Priority为0。Client不会向隐藏成员发送请求,因此隐藏成员不会收到Client的Request。
slaveDelay:单位是秒,将Secondary成员配置为延迟备份节点,要求Priority为0,表示该成员比Primary成员滞后指定的时间,才能将Primary上进行的写操作同步到本地。为了数据读取的一致性,应将延迟备份节点的hidden设置为true,避免用户读取到明显滞后的数据。Delayedmembersmaintainacopyofthedatathatreflectsthestateofthedataatsometimeinthepast.
votes:有效值是0或1,默认值是1,如果votes是1,表示该成员(votingmember)有权限选举Primary成员。在一个ReplicaSet中,最多有7个成员,其votes属性的值是1。
arbiterOnly:表示该成员是仲裁者,arbiter的唯一作用是就是参与选举,其votes属性是1,arbiter不保存数据,也不会为client提供服务。
buildIndexes:表示实在在成员上创建Index,该属性不能修改,只能在增加成员时设置该属性。如果一个成员仅仅作为备份,不接收Client的请求,将该成员设置为不创建index,能够提高数据同步的效率。
2,重新配置ReplicaSet
对ReplicaSet重新配置,必须连接到Primary节点;如果ReplicaSet中没有一个节点被选举为Primary,那么,可以使用forceoption(rs.reconfig(config,{force:true})),在Secondary节点上强制对ReplicaSet进行重新配置。
Theforceparameterallowsareconfigurationcommandtobeissuedtoanon-primarynode.Ifsetas{force:true},thisforcesthereplicasettoacceptthenewconfigurationevenifamajorityofthemembersarenotaccessible.Usewithcaution,asthiscanleadtorollbacksituations.
示例,在primary节点中,重新配置成员的优先级属性(priority)。
cfg=rs.conf()
cfg.members[0].priority=1
cfg.members[1].priority=1
cfg.members[2].priority=5
rs.reconfig(cfg)
3,增加成员
3.1,该使用默认的配置增加成员
--增加一个成员,用于存储数据
rs.add("host:port")
--增加一个arbiter,用于选举
rs.add("host:port",true)
3.2,使用配置文档增加成员
示例,为ReplicaSet增加一个延迟备份的隐藏节点,滞后Primary节点1hour,该节点不参与投票,也不创建index,仅仅作为数据备份。
rs.add({_id:4,host:"host:port",priority:0,hidden:true,slaveDelay:3600,votes:0,buildIndexes:true,arbiterOnly:false})
4,删除成员
rs.remove("host")
5,对replicaset重新配置,能够增加成员,删除成员,并能同时修改成员的属性
二,对ReplicaSet的成员进行操作
1,冻结当前成员,使当前成员在指定的时间内没有资格成为Primary,即当前成员在一定时间内保持Secondary身份
Makesthecurrentreplicasetmemberineligibletobecomeprimaryfortheperiodspecified.
rs.freeze(seconds)
2,强制Primary节点退化为Secondary节点
rs.stepDown()使当前Primary节点退化为Secondary节点,并激发选举Primary的事件。该函数使当前的Primary节点在指定的时间内,不能成为Primary节点。在一定的时间内,如果有Secondary节点满足条件,那么该Secondary节点被选举为Primary节点;如果没有Secondary节点满足条件,那么原Primary节点参与选举。stepDown函数,使Primary节点退化为Secondary,并在一段时间内不能参与选举。
Forcestheprimaryofthereplicasettobecomeasecondary,triggeringanelectionforprimary.Themethodstepsdowntheprimaryforaspecifiednumberofseconds;duringthisperiod,thestepdownmemberisineligiblefrombecomingprimary.
rs.stepDown(stepDownSecs,secondaryCatchUpPeriodSecs)
3,强制当前成员从指定成员同步数据
rs.syncFrom("host:port");
4,使当前的Secondary节点能够读取数据
默认情况下,Secondary节点是不能读取数据的
rs.slaveOk()
三,查看ReplicaSet的状态
set字段:ReplicaSet的name
stateStr:成员状态的描述信息
name:该成员的host和端口
syncTo:该成员从哪个成员同步数据,可以使用rs.syncFrom()强制同步的Path,从指定的Target成员同步数据。
{
"set":"rs0",
"myState":1,
"heartbeatIntervalMillis":NumberLong(2000),
"members":[
{
"_id":0,
"name":"cia-sh-05:40004",
"health":1,
"state":2,
"stateStr":"SECONDARY",
"uptime":240973,
"optime":{
"ts":Timestamp(1473336939,1),
"t":NumberLong(5)
},
"optimeDate":ISODate("2016-09-08T12:15:39.000Z"),
"lastHeartbeat":ISODate("2016-09-10T04:39:55.041Z"),
"lastHeartbeatRecv":ISODate("2016-09-10T04:39:56.356Z"),
"pingMs":NumberLong(0),
"syncingTo":"cia-sh-06:40001"
},.....
]
}
三,ReplicaSet的操作日志
MongoDB的Replication实际上是基于操作日志(operationlog)的复制。Replication进程的整个过程是:Replication将Primary节点中执行的写操作记录到oplog集合中,Secondary成员读取Primary成员的oplog集合,重做(redo)oplog中记录的写操作,最终,ReplicaSet中的各个成员达到数据的一致性。
oplog集合中记录的操作是基于单个doc的,也就是说,如果一条命令只影响一个doc,那么Replication向oplog集合中插入一个操作命令;如果一个命令影响多个doc,那么Replication将该命令拆分成多个等效的操作命令,每个操作命令只会影响一个doc,最终向oplog集合中插入的是多个操作命令。
1,oplog集合
oplog集合是一个特殊的固定集合,存储的是Primary节点的操作日志,每个ReplicaSet的成员都一个oplog的副本:local.oplog.rs,该集合存储在每个成员的local数据库中。ReplicaSet中的每个成员都有一个oplog集合,用于存储当前节点的操作记录,其他成员能够从任何一个成员的oplog中同步数据。
Theoplog(operationslog)isaspecialcappedcollectionthatkeepsarollingrecordofalloperationsthatmodifythedatastoredinyourdatabases.MongoDBappliesdatabaseoperationsontheprimaryandthenrecordstheoperationsontheprimary’soplog.Thesecondarymembersthencopyandapplytheseoperationsinanasynchronousprocess.Allreplicasetmemberscontainacopyoftheoplog,inthelocal.oplog.rscollection,whichallowsthemtomaintainthecurrentstateofthedatabase.
2,oplog的大小
oplog集合是一个固定集合,其大小是固定的,在第一次开始ReplicaSet的成员时,MongoDB创建默认大小的oplog。在MongoDB3.2.9版本中,MongoDB默认的存储引擎是WiredTiger,一般情况下,oplog的默认大小是数据文件所在disk空闲空间(diskfreespace)的5%,最小不会低于990MB,最大不会超过50GB。
3,修改oplog的大小
修改的过程主要分为三步:
- 以单机模式重启mongod
- 启动之后,重新创建oplog,并保留最后一个记录作为种子
- 以复制集方式重启mongod
详细过程是:
step1:以单机模式重启mongod
对于Primary成员,首先调用stepDown函数,强制Primary成员转变为Secondary成员
rs.stepDown()
对于secondary成员,调用shutdownServer()函数,关闭mongod
useadmin
db.shutdownServer()
启动mongod实例,不要使用replset参数
mongod--port37017--dbpath/srv/mongodb
step2:创建新的oplog
有备无患,备份oplog文件
mongodump--dblocal--collection'oplog.rs'--port37017
将oplog中最后一条有效记录保存到temp集合中,作为新oplog的seed
uselocal
db.temp.drop()
db.temp.save(db.oplog.rs.find({},{ts:1,h:1}).sort({$natural:-1}).limit(1).next())
db.oplog.rs.drop()
重建新的oplog集合,并将temp集合中一条记录保存到oplog中,size的单位是Byte
db.runCommand({create:"oplog.rs",capped:true,size:(2*1024*1024*1024)})
db.oplog.rs.save(db.temp.findOne())
step3:以复制集模式启动mongod,replset参数必须制定正确的ReplicaSet的名字
db.shutdownServer()
mongod--replSetrs0--dbpath/srv/mongodb
三,查看mongod的开机日志
在local.startup_log集合中,存储mongod每次启动时的开机日志
参考文档:
ThelocalDatabase
ReplicaSetConfiguration
ReplicaSetOplog
ChangetheSizeoftheOplog
本文内容总结:
原文链接:https://www.cnblogs.com/ljhdo/p/4583276.html