MongoDB选举机制

复制集概述

MongoDB复制集是指MongoDB实例通过复制并应用其他实例的oplog达到数据冗余的技术。MongoDB复制集一般由一个主服务器(Primary)和若干个备服务器(Secondary)组成。其中Primary用于处理客户端的请求,通过Primary将数据写入;Secondary从Primary同步数据,保存副本。当Primary服务器崩溃时,MongoDB复制集通过选举机制将其中一个Secondary服务器升级为Primary,保证复制集的高可用。
MongoDB在3.2版本对选举机制进行了一次较大的改动,可以通过shell查看选举协议版本:

PRIMARY> rs.conf().protocolVersion
NumberLong(1)

新的版本protocolVerson为1,通过MongoDB r3.2.0代码可以看到,心跳和选举基本以protocolVersion是否为1分叉处理。下面主要以PV1版本开始介绍MongoDB的选举机制,围绕选举周边只做简单介绍。

选举机制

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

心跳检查

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

在实现的时候主要由两个异步的过程分别处理心跳响应和超时,抛开复杂的条件检查,核心逻辑主要包括:
- Secondary节点权重比Primary节点高时,发起替换选举;
- Secondary节点发现集群中没有Primary时,发起选举;
- Primary节点不能访问到大部分(Majority)成员时主动降级;

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

选举发起

发起选举的节点需要首先做一些条件判断,比如节点位于备选节点列表中、POV包含复制集Majority等,真实情况的条件判断更加复杂。然后将自己标记为选举过程中,并发起投票请求。

投票

投票发起者向集群成员发起Elect请求,成员在收到请求后经过会一系列检查,如果通过检查则为发起者投一票。一轮选举中每个成员最多投一票,在PV0中用30秒“选举锁”避免为其他发起者重复投票,这导致了如果新选举的Primary挂掉,可能30秒内不会有新的Primary选举产生;在PV1中通过为投票引入单调递增的Term解决重复投票的问题。

如果投票发起者获得超过半数的投票,则选举通过成为Primary节点,否则重新发起投票。

注意

  • MongoDB选举需要获得大多数投票才能通过,在一轮选举中两个节点得票相同则重新选举,为避免陷入无限重复选举,MongoDB建议复制集的成员个数为奇数个,当Secondary节点个数为偶数时,可以增加一个Arbiter节点,。
  • PV0版本中,所有成员都可以投否决票,一个否决票会将得票数减少10000,所以一般可以认为只要有成员反对,则该节点不能成为Primary。PV1版本取消了否决票。
  • 选举过程中,复制集没有主节点,所有成员都是只读状态。

参考

MongoDB选举过程
MongoDB复制集原理

你可能感兴趣的:(分布式系统)