MongoDB同步原理解析

转载 2018年04月17日 18:24:15

MongoDB副本集数据同步](https://docs.mongodb.com/manual/core/replica-set-sync/)主要包含2个步骤

  1. intial sync,可以理解为全量同步
  2. replication,追同步源的oplog,可以理解为增量同步

本文是对MongoDB高可用复制集原理的补充,会详细介绍MongoDB数据同步的实现原理。

initial sync

Secondary节点当出现如下状况时,需要先进行全量同步

  1. oplog为空
  2. local.replset.minvalid集合里_initialSyncFlag字段设置为true
  3. 内存标记initialSyncRequested设置为true

这3个场景分别对应

  1. 新节点加入,无任何oplog,此时需先进性initial sync
  2. initial sync开始时,会主动将_initialSyncFlag字段设置为true,正常结束后再设置为false;如果节点重启时,发现_initialSyncFlag为true,说明上次全量同步中途失败了,此时应该重新进行initial sync
  3. 当用户发送resync命令时,initialSyncRequested会设置为true,此时会重新开始一次initial sync

intial sync流程

  1. 全量同步开始,设置minvalid集合的_initialSyncFlag
  2. 获取同步源上最新oplog时间戳为t1
  3. 全量同步集合数据 (耗时)
  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

Replication

initial sync结束后,接下来Secondary就会『不断拉取主上新产生的oplog并重放『』,这个过程在Secondary同步慢问题分析也介绍过,这里从另一个角度再分析下。

  • producer thread,这个线程不断的从同步源上拉取oplog,并加入到一个BlockQueue的队列里保存着。
  • replBatcher thread,这个线程负责逐个从producer thread的队列里取出oplog,并放到自己维护的队列里。
  • sync线程将replBatcher thread的队列分发到默认16个replWriter线程,由replWriter thread来最终重放每条oplog。

问题来了,为什么一个简单的『拉取oplog并重放』的动作要搞得这么复杂?

性能考虑,拉取oplog是单线程进行,如果把重放也放到拉取的线程里,同步势必会很慢;所以设计上producer thread只干一件事。

为什么不将拉取的oplog直接分发给replWriter thread,而要多一个replBatcher线程来中转?

oplog重放时,要保持顺序性,而且遇到createCollection、dropCollection等DDL命令时,这些命令与其他的增删改查命令是不能并行执行的,而这些控制就是由replBatcher来完成的。

注意事项

  • initial sync单线程复制数据,效率比较低,生产环境应该尽量避免initial sync出现,需合理配置oplog,按默认『5%的可用磁盘空间』来配置oplog在绝大部分场景下都能满足需求,特殊的case(case1case2)可根据实际情况设置更大的oplog。
  • 新加入节点时,可以通过物理复制的方式来避免initial sync,将Primary上的dbpath拷贝到新的节点,直接启动,这样效率更高。
  • 当Secondary上需要的oplog在同步源上已经滚掉时,Secondary的同步将无法正常进行,会进入RECOVERING的状态,需向Secondary主动发送resyc命令重新同步。3.2版本目前有个bug,可能导致resync不能正常工作,必须强制(kill -9)重启节点,详情参考SERVER-24773
  • 生产环境,最好通过db.printSlaveReplicationInfo()来监控主备同步滞后的情况,当Secondary落后太多时,要及时调查清楚原因。
  • 当Secondary同步滞后是因为主上并发写入太高导致,(db.serverStatus().metrics.repl.buffer.sizeBytes持续接近db.serverStatus().metrics.repl.buffer.maxSizeBytes),可通过调整Secondary上replWriter并发线程数来提升。

作者简介

张友东,阿里巴巴技术专家,主要关注分布式存储、Nosql数据库等技术领域,先后参与TFS(淘宝分布式文件系统)Redis云数据库等项目,目前主要从事MongoDB云数据库的研发工作,致力于让开发者用上最好的MongoDB云服务。



http://www.mongoing.com/archives/3076


MongoDB Master+Master同步

MongoDB支持主主复制,但是在大部分情况下官方不推荐使用。
  • tianwei7518
  • tianwei7518
  • 2015-03-18 20:29:31
  • 837

Mongodb分片+副本集配置

一:分片介绍 这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB集群。 MongoDB 的数据分块...
  • YABIGNSHI
  • YABIGNSHI
  • 2015-07-24 17:58:02
  • 3205

mongodb有关的研究

mongodb有关的研究
  • a9529lty
  • a9529lty
  • 2011-06-01 08:49:00
  • 1918

MongoDB+Struts2+JQuery.formValidator插件的web应用示例

/** * 此次应用涉及的几个小知识点为: * 1.MongoDB的插入和更新操作 * 2.Struts2的最基本使用 * 3.单例设计模式的简单使用 * 4.JQuery form验证表单插件的使用...
  • tujiyue
  • tujiyue
  • 2011-06-12 17:26:00
  • 3402

MongoDB + Spark: 完整的大数据解决方案

MongoDB上海的活动已经结束快1个月了,我们再来回顾一下TJ在大会上进行的精彩分享吧~ MongoDB + Spark: 完整的大数据计算解决方案。 Spark介绍 按照官方的定义...
  • u011596455
  • u011596455
  • 2017-08-09 23:02:45
  • 1201

httpclient4.5+disruptor3.3.2+mongodb3.2+jsoup写的一个抓取小程序

最近由于工作上接手了一个storm的系统,storm采用dubbo接口接收数据,存队列,这里队列用的是jdk自带的阻塞队列ArrayBlockQueue,再做了几轮压测之后发现ArrayBlockQu...
  • jiangjun_3567031
  • jiangjun_3567031
  • 2016-01-14 17:54:14
  • 613

mongoDB命令

mongoDB有的帮助命令 help:整个数据库的帮助,可以看成是一个总纲 db.help():管理数据库的帮助(创建表,删除表,姑且这样说以理解) db.mycoll.help()...
  • wenmeishuai
  • wenmeishuai
  • 2015-06-02 13:40:30
  • 216

mongoDB的复制集2----同步机制(工作原理,oplog详解,初始化同步的过程

一、复制集是怎么工作的 1-1.复制集工作原理     Mongodb复制集由一组Mongod实例(进程)组成,包含一个Primary节点和多个Secondary节点,Mongodb Driver(客...
  • oChangWen
  • oChangWen
  • 2016-08-29 20:46:38
  • 2319

学习MongoDB--(9-1):复制(主从复制--基本示例和原理介绍)

在生产环境中,MongoDB极力推荐使用其复制功能!数据库管理员的一个十分重要的工作就是确保复制设置正确且运转良好!复制可以用来应对故障切换、数据集成、读扩展和离线批处理的数据源!马上就来讲一下复制的...
  • DrifterJ
  • DrifterJ
  • 2012-08-26 20:45:06
  • 4553
收藏助手
不良信息举报
您举报文章:MongoDB同步原理解析
举报原因:
原因补充:

(最多只允许输入30个字)