阿里云数据库ApsaraDB 关注
手机版
  1. 云栖社区>
  2. 阿里云数据库ApsaraDB>
  3. 博客>
  4. 正文

MongoDB复制集同步原理解析

yunnotes 2016-07-18 09:58:45 浏览5343 评论3 发表于: 阿里云数据库ApsaraDB

数据存储与数据库 MongoDB

摘要: MongoDB副本集数据同步](https://docs.mongodb.com/manual/core/replica-set-sync/)主要包含2个步骤 intial sync,可以理解为全量同步 replication,追同步源的oplog,可以理解为增量同步 本文是对MongoDB高

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(case1, case2)可根据实际情况设置更大的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并发线程数来提升。
本文为云栖社区原创内容,未经允许不得转载,如需转载请发送邮件至yqeditor@list.alibaba-inc.com;如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:yqgroup@service.aliyun.com 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。

用云栖社区APP,舒服~

【云栖快讯】浅析混合云和跨地域网络构建实践,分享高性能负载均衡设计,9月21日阿里云专家和你说说网络那些事儿,足不出户看直播,赶紧预约吧!  详情请点击

网友评论

1F
towells

intial sync 的同步步骤讲解很好,非常详细,感谢ING,但是 initial sync 是怎么实现的呢 ?希望后面有机会能再讲解。

2F
博文编辑

博主您好,我是电子工业出版社博文视点的编辑,看到您发表的关于MongoDB的系列文章,觉得内容很好,不知道您是否有兴趣出版图书呢:)我的qq472954195,邮箱是chenxm@Phei.com.cn

3F
肖枫

东哥,你是怎么知道这些细节的。是通过看代码吗?

关注
yunnotes
张友东,花名林青,阿里云数据库组技术专家,主要...
82篇文章|355关注
基于飞天分布式系统和高性能存储,提供三节点副本集的高可用架构,容灾切换,故障迁移完全透明化。并提供专业的数据库在...

为企业和开发者提供稳定、安全、智能的把网站域名或应用资源转换为计算机用于互连的数字 IP地址,从而将最终用户的访...

提供海量、安全和高可靠的云存储服务。RESTful API的平台无关性,容量和处理能力的弹性扩展,按实际容量付费...

为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...