mongodb数据备份原理_Mongodb复制同步原理

1.预备知识

1.1 同步分2种:

1)intial sync,可以理解为全量同步。

2)replication,追同步源的oplog,可以理解为增量同步。

Secondary 在什么情况下会intial sync?

a)新加入节点,无任何oplog

b)local.replset.minvalid集合里_initialSyncFlag字段设置为true

c)内存标记initialSyncRequested设置为true

对应下面3种情况:

1.新节点加入,无任何oplog,此时需要intial sync。

2.initial sync开始时,会主动将_initialSyncFlag字段设置为true,正常结束后再设置为false;如果节点重启时,发现_initialSyncFlag为true,说明上次全量同步中途失败了,此时应该重新进行initial sync。

3.当用户发送resync命令时,initialSyncRequested会设置为true,此时会重新开始一次initial sync。

* intial sync流程(对应3.2 版本)

1 ) 全量同步开始,设置minvalid集合的_initialSyncFlag

2) 获取同步源上最新oplog时间戳为t1

3) 创建集合(包含_id索引),全量同步集合数据 (此步耗时)

4) 获取同步源上最新oplog时间戳为t2

5) 重放[t1, t2]范围内的所有oplog

6) 获取同步源上最新oplog时间戳为t3

7) 重放[t2, t3]范围内所有的oplog

8) 建立集合其他所有索引 (此步耗时)

9) 获取同步源上最新oplog时间戳为t4

10) 重放[t3, t4]范围内所有的oplog

11) 全量同步结束,清除minvalid集合的_initialSyncFlag

intial sync结束后,Secondary会不断的拉取主库上新生成的oplog并重放,转成Replication。

* Replication 流程:

mongo_repl01.png?version=1&modificationDate=1498565019000&api=v2

上图很清晰的看到Repliction的流程。

producer thread:这个线程不断的从同步源上拉取oplog,并加入到一个BlockQueue的队列里保存着。

replBatcher thread:这个线程负责逐个从producer thread的队列里取出oplog,并放到自己维护的队列里。

sync线程将replBatcher thread的队列分发到默认16个replWriter线程,由replWriter thread来最终决定哪些可以并发重放oplog。

从上面看出,这是个PC(生产者-消费者模型),因为拉取主库上的线程是单线程,如果把重放也放到拉取线程里,性能跟不上去,所以设计加入producer thread、replBatcher thread,提升复制性能。

replBatcher thread 主要是控制哪些可以并发。

replWriterThreadCount:MongoDB 3.2开始多线程复制,取值1-256,默认16。

1.2 全量同步的改进:

Mongodb  3.2 复制可以表述为如下:

记录最新oplog(t1),创建集(含_id索引),记录最新oplog(t2),重放[t1,t2]之间的oplog,记录最新oplog(t3)

重放[t2,t3]之间的oplog,拷贝集合数据,记录最新oplog(t4),重放[t3,t4]之间的oplog

创建其他所有索引

拉取增量oplog并应用

Mongodb  3.4 复制可以表述为如下:

创建集合(包含所有索引)

拷贝集合数据

应用本地缓存的oplog

拉取主库的oplog至本地临时集合

其实在上图3.2版本会在每个阶段都会拷贝增量的oplog。

从上面可以看出:3.4 相对于3.2  有2个大改进,

1) 3.4在拷贝数据的同时创建所有的索引,3.2是先创建_id索引,再拷贝集合数据,拷贝集合数据后再创建其他所有索引。

2) 3.4在拷贝数据的同时会把主库增量的oplog 拷贝到本地local库下。等待集合数据全部拷贝完,直接读取本地local库下临时集合中的oplog。目的:提升追增量oplog的效率,同时也可以避免主库上oplog_size 不够大的情况。

1.3 优化主从复制

1.3.1 repl Buffer size的大小:默认是256MB。

hhlshd2:SECONDARY> db.serverStatus().metrics.repl.buffer.maxSizeBytes

NumberLong(268435456)

* 这个暂时没找到可以调整的参数。

1.3.2 调整从库replWriter 的数量:

参数:replWriterThreadCount  默认是16,从3.2 开始引入,取值范围: 1-256

hhlshd2:SECONDARY> db.adminCommand({getParameter:1, replWriterThreadCount:true})

{ "replWriterThreadCount" : 16, "ok" : 1 }

1.3.3 replApplyBatchSize:批量oplog的条数。

hhlshd2:SECONDARY> db.adminCommand({getParameter:1, replApplyBatchSize:true})

{ "replApplyBatchSize" : 1, "ok" : 1 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值