美文网首页
【mongoDB】MongoDB 主从数据同步原理和过程

【mongoDB】MongoDB 主从数据同步原理和过程

作者: Bogon | 来源:发表于2023-09-05 09:52 被阅读0次

MongoDB中的副本集是一组维护相同数据集合的 mongod进程。
副本集提供了冗余和高可用性,并且这是所有生产部署的基础。

image.png image.png

复制集中的OpLog

oplog(操作日志)是一个特殊的有上限的集合(老的日志会被overwrite),它保存所有修改数据库中存储的数据的操作的滚动记录。

从MongoDB 4.0开始,与其他有限集合不同,oplog集合可以超过其配置的大小限制,以避免大多数提交点被删除。

MongoDB在主节点上应用数据库操作,然后将这些操作记录到主节点的oplog上。然后从节点成员会以异步的方式复制并应用这些操作。

所有副本集成员都包含一个oplog的副本,其位于local.oplog.rs 集合中,该集合可以让副本集成员维护数据库的当前状态。

为了便于复制,所有副本集成员将心跳(ping)发送给所有其他成员。任何从节点成员都可以从任何其他成员导入oplog条目。

oplog中的每个操作都是幂等的,也就是说,对目标数据集应用一次或多次oplog操作都会产生相同的结果。

什么是OpLog?

MongoDB在主节点上应用数据库操作,然后将这些操作记录到oplog中。然后从节点通过异步进程复制和应用(数据同步)这些操作。在local.oplog.rs集合中,所有复制集成员都包含oplog的一个副本用来维护数据库的当前状态。

MongoDB 4.4支持以小时为单位指定最小操作日志保留期,其中MongoDB仅在以下情况下删除操作日志条目:

  • oplog已达到配置的最大大小
  • oplog条目早于配置的小时数
$ mongo -h xx.xx.xx.xx --port=27017 --username=username --password='XXX' --authenticationDatabase=admin

> rs.printReplicationInfo()   
configured oplog size:   51200MB
log length start to end: 24019311secs (6672.03hrs)
oplog first event time:  Mon Dec 06 2021 15:28:16 GMT+0800 (CST)
oplog last event time:   Sat Sep 10 2022 15:30:07 GMT+0800 (CST)
now:                     Sat Sep 10 2022 15:30:09 GMT+0800 (CST)

> db.getReplicationInfo() 
{
    "logSizeMB" : 51200,
    "usedMB" : 6221.35,
    "timeDiff" : 24019341,
    "timeDiffHours" : 6672.04,
    "tFirst" : "Mon Dec 06 2021 15:28:16 GMT+0800 (CST)",
    "tLast" : "Sat Sep 10 2022 15:30:37 GMT+0800 (CST)",
    "now" : "Sat Sep 10 2022 15:30:38 GMT+0800 (CST)"
}

> db.printSlaveReplicationInfo()
source: 192.168.69.136:27020
    syncedTo: Sat Sep 10 2022 15:33:11 GMT+0800 (CST)
    0 secs (0 hrs) behind the primary </pre>

在设计OpLog时要考虑什么?

看下MongoDB在设计OpLog时考虑了什么?这对我们在使用和配置oplog有很好的帮助。

  • 查看操作日志的状态?
  • 操作日志设置多大?默认设置是多大呢?
  • 操作日志保存多久?
  • 哪些情况需要设置更大的?
  • 对操作慢的管理和设置?

复制集中的数据同步

复制集中的数据同步是为了维护共享数据集的最新副本,包括复制集的辅助成员同步或复制其他成员的数据。MongoDB使用两种形式的数据同步:

  • 初始同步(Initial Sync) 以使用完整的数据集填充新成员, 即全量同步
  • 复制(Replication) 以将正在进行的更改应用于整个数据集, 即增量同步

初始同步(Initial Sync)

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

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

这3个场景分别对应

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

intial sync流程

  • 全量同步开始,设置minvalid集合的_initialSyncFlag
  • 获取同步源上最新oplog时间戳为t1
  • 全量同步集合数据 (耗时)
  • 获取同步源上最新oplog时间戳为t2
  • 重放[t1, t2]范围内的所有oplog
  • 获取同步源上最新oplog时间戳为t3
  • 重放[t2, t3]范围内所有的oplog
  • 建立集合所有索引 (耗时)
  • 获取同步源上最新oplog时间戳为t4
  • 重放[t3, t4]范围内所有的oplog
  • 全量同步结束,清除minvalid集合的_initialSyncFlag

复制(Replication),增量同步

initial sync结束后,接下来Secondary就会『不断拉取主上新产生的otlog并重放』,这个过程在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命令重新同步。
  • 生产环境,最好通过db.printSlaveReplicationInfo()来监控主备同步滞后的情况,当Secondary落后太多时,要及时调查清楚原因。
  • 当Secondary同步滞后是因为主上并发写入太高导致,(db.serverStatus().metrics.repl.buffer.sizeBytes持续接近db.serverStatus().metrics.repl.buffer.maxSizeBytes),可通过调整Secondary上replWriter并发线程数来提升。

参考

MongoDB 副本集Oplog
https://mp.weixin.qq.com/s/cYincwfjGPw2wXTWVSA9kg

关于MongoDB Oplog窗口时间
https://www.jianshu.com/p/e988b5184780

MongoDB 产品说明
https://mp.weixin.qq.com/s/CyUA88AmLF-tfVQVWmhMEg

NoSQL数据库之MongoDB
https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzI0MDQ4MTM5NQ==&scene=1&album_id=2893529094972538880&count=3#wechat_redirect

相关文章

网友评论

      本文标题:【mongoDB】MongoDB 主从数据同步原理和过程

      本文链接:https://www.haomeiwen.com/subject/ikchvdtx.html