mongodb复制集

基本概念

复制集可保证数据库具有以下特性:

  • 高可用性
  • 数据安全
  • 分流/分工

复制集节点主要由一个主节点和众多副节点组成。

主节点:主要负责数据的写入操作。在默认的情况下,主节点也可以处理读取请求,但是在读取请求中设置了一些特殊选项后,副节点也可以处理读取请求
副节点:主要从主节点(或者复合条件的副节点)处复制数据

一个复制集群中的任意两个节点都会进行相互的心跳检测,用以沟通各个节点的健康状态

  • 每个节点都会向其他的所有节点发送心跳请求
  • 默认每隔2秒发送一次,如果请求超过10秒,则认为该心跳超时
  • 复制集中的节点数量最多为50个(心跳发送的数量是与节点数量呈O(n^2),节点越多,心跳所占用的资源越大)

复制集选举

复制集中的主节点不是一成不变的。当主节点变成不可用的状态时,MongoDB会通过一些选举算法,在其他副节点中进行主节点的重新选举。

触发选举的事件:

  • 主节点与副节点之间的心跳超时
  • 初始化复制集
  • 新节点加入复制集

选举过程:

  • 候选节点发起选举(首先投自己一票),其他节点会比较自己与候选节点的数据同步情况,如果候选节点的数据同步情况比自己要高,就会投赞成票,反之就会投反对票
  • 得票超过选票半数的候选节点会当选为新的主节点。否则的话,该节点将会继续当作副节点进行工作,由下一个候选节点进行新的投票
  • 复制集当中最多可以有7个投票节点

投票节点

  • 不同步数据,只参与投票
  • 不能成为主节点(不能投给自己)

同步过程

初始化同步

当副节点出现以下情况时,会进行初始化同步:

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

其对应的场景为:

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

初始化同步过程中,首先会将该副节点中的所有数据清空,然后将主节点中的数据库集合索引文档等复制到该节点中,示意图如下:

复制过程具有延迟性,主节点在副节点复制数据的过程中还会接受写入操作,副节点复制完成后,两边的数据不一致

副节点将数据clone完成后,会拿取主节点的oplog(写库记录),将这段时间内的写入操作记录,复制到副节点中,按照该操作记录进行同样的操作。过程有点类似于redis的快照与日志两种持久化方式的结合。当然,其中还有很多细节部分,待了解清楚。

初始化同步为单线程操作,效率较低,应尽量避免在生产环境使用。新加入副节点时,可以直接将主节点的dbpath目录进行物理拷贝,然后直接启动副节点,可以一定程度上避免生产环境下的初始化同步过程。

写库记录

  • 写库记录可以被重复使用,但oplog的重放是“幂等”的,即执行多次与执行一次的效果是一样的
  • 数据同步时,MongoDB会使用多线程分批次使用写库日志
  • 写库记录会记录具体的某一篇文档的操作(同时更新100篇文档,至少会产生100条写库记录)

写库记录可以通过local库中的oplog.rs集合进行查看,该集合是具有“封顶”特点的集合,该集合的大小固定,当集合内的数据超过设定的大小时,会对最开始的文档进行覆盖。

oplog的大小默认为当前分区可用空间的5%,也可以通过命令--oplogSize=xxx(单位为M)手动进行设置(最大50G)。

如果oplog的配置设置的太小,则可能会出现oplog中的文档被覆盖,从而造成从节点复制停止的情况。因为oplog设置的太小,会存在这样一种情况:当从节点还未将某一条写库记录进行复制并操作时,该记录就被覆盖掉了。此时MongoDB服务器为了保证数据的一致性,就会认为当前复制集状态错误,而停止从节点的复制。

所以在业务中如果存在大量的针对不止一条文档的操作时,oplog的大小尽量的设置大一些。

在后面的MongoDB版本中,优化了oplog的删除策略,使用批量删除,并不是等oplog满了之后才进行删除

其他关于复制集的文章:

mongodb复制集:https://www.cnblogs.com/jay54520/p/8428678.html
MongoDB复制集原理、搭建及复制集简单维护:https://blog.csdn.net/qq_24598601/article/details/81150614
MongoDB复制集原理:https://www.cnblogs.com/purpleraintear/p/6035111.html
MongoDB oplog详解:https://www.cnblogs.com/Joans/p/7723554.html

posted @ 2021-08-20 16:37  Mr_Kahn  阅读(227)  评论(0)    收藏  举报