复制集

MongoDB复制集是指MongoDB实例通过复制并应用其他实例的oplog达到数据冗余的技术。

MongoDB复制集一般由一个主服务器(Primary)和若干个备服务器(Secondary)组成。

其中Primary用于处理客户端的请求,通过Primary将数据写入;Secondary从Primary同步数据,保存副本。

当Primary服务器崩溃时,MongoDB复制集通过选举机制将其中一个Secondary服务器升级为Primary,保证复制集的高可用。

选举机制

MongoDB节点之间维护心跳检查,主节点选举由心跳触发。

心跳检查

MongoDB复制集成员会向自己之外的所有成员发送心跳并处理响应信息,因此每个节点都维护着从该节点POV看到的其他所有节点的状态信息。节点根据自己的集群状态信息判断是否需要更换新的Primary。

在实现的时候主要由两个异步的过程分别处理心跳响应和超时,抛开复杂的条件检查,核心逻辑主要包括:

  • Secondary节点权重比Primary节点高时,发起替换选举;
  • Secondary节点发现集群中没有Primary时,发起选举;
  • Primary节点不能访问到大部分(Majority)成员时主动降级;

降级操作会断开链接,终止用户请求等。

选举主节点

Secondary节点检测到当前集群没有存活的主节点,则尝试将自身选举为Primary。主节点选举是一个二阶段过程+多数派协议。

第一阶段

以自身POV,检测自身是否有被选举的资格:

  1. 能ping通集群的过半数节点
  2. priority必须大于0
  3. 不能是arbitor节点 如果检测通过,向集群中所有存活节点发送FreshnessCheck(询问其他节点关于“我”是否有被选举的资格)

第二阶段

发起者向集群中存活节点发送Elect请求,仲裁者收到请求的节点会执行一系列合法性检查,如果检查通过,则仲裁者给发起者投一票,并获得30秒钟“选举锁”,选举锁的作用是:在持有锁的时间内不得给其他发起者投票。

发起者如果或者超过半数的投票,则选举通过,自身成为Primary节点。获得低于半数选票的原因,除了常见的网络问题外,相同优先级的节点同时通过第一阶段的同僚仲裁并进入第二阶段也是一个原因。因此,当选票不足时,会sleep[0,1]秒内的随机时间,之后再次尝试选举。

参考

  1. https://docs.mongodb.com/manual/core/replica-set-elections/
  2. MongoDB 复制集原理