ElasticSearch——详解主从模式,以及主节点的选取算法(二)

参考源:详解主从模式,以及主节点的选取算法

整体流程可以概括为:

  • 选举临时Master,如果本节点当选,则等待确立Master
  • 如果其他节点当选,则尝试加入集群,然后启动节点失效探测器

具体如下图所示:

执行本流程的线程池为:generic。
下面具体分析每个步骤的实现。

选举临时Master

选举过程的实现位于 ZenDiscovery#findMaster。该函数查找当前集群的活跃 Master,或者从候选者中选择新的Master。如果选主成功,则返回选定的Master,否则返回空。

为什么是临时Master?因为还需要等待下一个步骤,等该节点的得票数足够时,才确立为真正的Master。

临时Master的选举过程如下

"ping”所有节点,

获取节点列表fullPingResponses,ping结果不包含本节点,把本节点单独添加到fullPingResponses中。

构建两个列表。

activeMasters列表:

存储集群当前活跃Master列表。遍历第一步获取的所有节点, 将每个节点所认为的当前Master节点加入activeMasters列表中(不包括本节点)。在遍历过程中,如果配置了discovery.zen.master_election.ignore_non_master_pings 为true(默认为false),而节点又不具备Master资格,则跳过该节点。

具体流程如下图所示:


这个过程是将集群当前已存在的Master加入activeMasters列表,正常情况下只有一个。如果集群已存在Master,则每个节点都记录了当前Master是哪个,考虑到异常情况下,可能各个节点看到的当前
Master不同
在构建activeMasters列表过程中,如果节点不具备Master资格,则可以通过ignore_non_master_pings选项忽略它认为的那个Master。

masterCandidates列表

存储master候选者列表
遍历第一步获取列表,去掉不具备Master资格的节点,添加到这个列表中。

选举

如果activeMasters为空,则从masterCandidates中选举,结果可能选举成功,也可能选举失败。
如果不为空, 则从activeMasters中选择最合适的作为Master

整体流程如下图所示:

从masterCandidates中选主

与选主的具体细节实现封装在ElectMasterService类中,例如,判断候选者是否足够,选择具体的节点作为Master等。
(一)从masterCandidates中选主时,首先需要判断当前候选者人数是否达到法定人数,否则选主失败。

(二)当候选者人数达到法定人数后,从候选者中选一个出来做Master:这里只是将节点排序后选择最小的节点作为Master。排序时使用自定义的比较函数 MasterCandidate::compare,早期的版本中只是对节点 ID 进行排序,现在会优先把集群状态版本号高的节点放在前面。

compare内部的节点比较函数compareNodes的实现:对于排序效果来说,如果传入的两个节点中,有一个节点具备 Master 资格,而另一个不具备,则把有 Master 资格的节点排在前面。如果都不具备Master资格,或者都具备Master资格,则比较节点ID。
但是,masterCandidates列表中的节点都是具备Master资格的。compareNodes比较函数的两个if判断是因为在别的函数调用中会存在节点列表中可能存在不具备Master资格节点的情况。因此此处只会比较节点ID。

从activeMasters列表中选择

该列表存储着集群当前存在活跃的Master,从这些已知的Master节点中选择一个作为选举结果
选择过程非常简单,取列表中的最小值,比较函数仍然通过compareNodes实现,activeMasters列表中的节点理论情况下都是具备Master资格的。

投票与得票的实现

在ES中,发送投票就是发送加入集群(JoinRequest)请求
得票就是申请加入该节点的请求的数量。
收集投票,进行统计的实现在ZenDiscovery#handleJoinRequest方法中,收到的连接被存储到
ElectionContext#joinRequestAccumulator中。
当节点检查收到的投票是否足够时,就是检查加入它的连接数是否足够,其中会去掉没有Master资格节点的投票

确立Master或加入集群

选举出的临时Master有两种情况:该临时Master是本节点或非本节点。两种情况需要单独处理。
现在准备向其发送投票。

如果临时Master是本节点:

(1)等待足够多的具备Master资格的节点加入本节点(投票达到法定人数),以完成选举。
(2)超时(默认为30秒,可配置)后还没有满足数量的join请求,则选举失败,需要进行新一轮选举。
(3)成功后发布新的clusterState。

如果其他节点被选为Master:

(1)不再接受其他节点的join请求。
(2)向Master发送加入请求,并等待回复。超时时间默认为1分钟(可配置),如果遇到异常,则默认重试3次(可配置)。这个步骤在joinElectedMaster方法中实现。
(3)最终当选的Master会先发布集群状态,才确认客户的join请求,因此,joinElectedMaster返回代表收到
了join请求的确认,并且已经收到了集群状态。本步骤检查收到的集群状态中的Master节点如果为空,或者
当选的Master不是之前选择的节点,则重新选举。

节点失效检测

节点失效检测会监控节点是否离线,然后处理其中的异常。
失效检测是选主流程之后不可或缺的步骤,不执行失效检测可能会产生脑裂(双主或多主)
这里需要需要启动两种失效探测器:

  • 在Master节点启动NodesFaultDetection,简称NodesFD定期探测加入集群的节点是否活跃
  • 在非Master节点启动MasterFaultDetection,简称MasterFD定期探测Master节点是否活跃

NodesFaultDetection和MasterFaultDetection都是通过定期(默认为1秒)发送的ping请求探测节点是否正常的,当失败达到一定次数(默认为3次),或者收到来自底层连接模块的节点离线通知时,开始处理节点离开事件

NodesFaultDetection事件处理

检查一下当前集群总节点数是否达到法定节点数(过半),如果不足,则会放弃 Master 身份,重新加入集群。为什么要这么做?设想下下图场景:
image.png
假设有5台机器组成的集群产生网络分区,2台组成一组,另外3台
组成一组,产生分区前,原Master为Node1。此时3台一组的节点会重新选举并成功选取Noded3作为Master,会不会产生双主?
NodesFaultDetection就是为了避免上述场景下产生双主。
对应处理方法在ZenDiscovery#handleNodeFailure中的NodeRemovalClusterStateTaskExecutor#execute中:主节点在探测到节点离线的事件处理中,如果发现当前集群节点数量不足法定人数,则放弃Master身份,从而避免产生双主

MasterFaultDetection事件处理

探测Master离线的处理很简单,重新加入集群。本质上就是该节点重新执行一遍选主的流程.
对应事件处理主要实现在方法 ZenDiscovery#handleMasterGone 中。

总得来说,选主流程在集群中启动,从无主状态到产生新主时执行,同时集群在正常运行过程中, Master探测到节点离开,非Master节点探测到Master离开时都会执行。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值