当前位置:   article > 正文

死磕Elasticsearch(二)选主流程_elasticsearch 选举算法

elasticsearch 选举算法

1 选举算法

     elasticsearch的选举算法是基于Bully算法改造的。
     Bully是Leader选举的基本算法之一。 它假定所有节点都有一个惟一的ID,该ID对节点进行排序。 任何时候的当前Leader都是参与集群的最高id节点。 该算法的优点是易于实现,但是,当拥有最大 id 的节点处于不稳定状态的场景下会有问题,例如 Master 负载过重而假死,集群拥有第二大id 的节点被选为 新主,这时原来的 Master 恢复,再次被选为新主,然后又假死…

     elasticsearch 通过推迟选举直到当前的 Master 失效来解决上述问题。但是推迟选举是怎么个推迟法,本人搜索了很多论坛还是没有找到解释,求知道的大佬们指导一下,本人的理解是只要es的进程还在,就不会重新选举,直到master节点的es节点挂了为止。那什么叫挂了呢,个人认为是从节点是向Master节点的9300端口发送数据的不能得到返回时。
    除此以外,用这种方式还容易产生脑裂,需要再通过法定得票人数过半的办法解决脑裂。

2 相关配置

    防止脑裂、防止数据丢失的极其重要的参数:
    discovery.zen.minimum_master_nodes=(master_eligible_nodes)/2+1
    这个参数的实际作用早已超越了其表面的含义,会用于至少以下多个重要时机的判断:

  1. 触发选主:进入选举临时的Master之前,参选的节点数需要达到法定人数。
  2. 决定Master:选出临时的Master之后,得票数需要达到法定人数,才确认选主成功。
  3. gateway选举元信息:向有Master资格的节点发起请求,获取元数据,获取的响应数量必须达到法定人数,也就是参与元信息选举的节点数。
  4. Master发布集群状态:成功向节点发布集群状态信息的数量要达到法定人数。
  5. NodesFaultDetection事件中是否触发rejoin:当发现有节点连不上时,会执行removeNode。接着审视此时的法定人数是否达标(discovery.zen.minimum_master_nodes),不达标就主动放弃Master身份执行rejoin以避免脑裂。
  6. Master扩容场景:目前有3个master_eligible_nodes,可以配置quorum为2。如果将master_eligible_nodes扩容到4个,那么quorum就要提高到3。此时需要先把discovery.zen.minimum_master_nodes配置设置为3,再扩容Master节点。这个配置可以动态设置:
PUT /_cluster/settings
{
	“persistent”: {
	“discovery.zen.minimum_master_nodes”: 3
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

7 Master减容场景:缩容与扩容是完全相反的流程,需要先缩减Master节点,再把quorum数降低。修改Master以及集群相关的配置一定要非常谨慎!配置错误很有可能导致脑裂,甚至数据写坏、数据丢失等场景。

3 流程概述

    ZenDiscovery(默认)过程就是这样的:

 1. 每个节点计算最低的已知节点ID,并向该节点发送领导投票。
 2. 如果一个节点收到足够多的票数,并且该节点也为自己投票,那么它将扮演领导者的角色,开始发布集群状态。
 3. 所有节点都会参数选举,并参与投票,但是,只有有资格成为 master 的节点的投票才有效(node.master为true)。
(就像皇上只在皇子中选一样。)
  • 1
  • 2
  • 3
  • 4

    有多少选票赢得选举的定义就是所谓的法定人数。 在弹性搜索中,法定大小是一个可配置的参数。 (一般配置成:可以成为master节点数n/2+1)。

4 流程分析

    整体流程可以概括为:选举临时Master,如果本节点当选,等待确立Master,如果其他节点当选,等待加入Master,然后启动节点失效探测器。流程图如下所示:
在这里插入图片描述

4.1 选举临时Master流程

临时Master的选举过程如下:
(1)“ping”所有节点,获取节点列表fullPingResponses,ping结果不 包含本节点,把本节点单独添加到fullPingResponses中。
(2)构建两个列表。 activeMasters列表:存储集群当前活跃Master列表。遍历第一步获 取的所有节点,将每个节点所认为的当前Master节点加入activeMasters 列表中(不包括本节点)。在遍历过程中,如果配置了

	discovery.zen.master_election.ignore_non_master_pings 为 true(默认为 false)
  • 1

而节点又不具备Master资格,则跳过该节点。

在这里插入图片描述

    这个过程是将集群当前已存在的Master加入activeMasters列表,正常情况下只有一个。如果集群已存在Master,则每个节点都记录了当前 Master是哪个,考虑到异常情况下,可能各个节点看到的当前Master不同,这种场景个人觉得会在节点之间网络延迟比较大的情况下出现,如不同机架的节点之间,网络延迟较大,在起动进程之后,出现选主结果不一致的情况。在构建activeMasters列表过程中,如果节点不具备Master资格,则 可以通过ignore_non_master_pings选项忽略它认为的那个Master。 (过滤掉没有)

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

(3)如果activeMasters为空,则从masterCandidates中选举,结果可 能选举成功,也可能选举失败。如果不为空,则从activeMasters中选择 最合适的作为Master。
整体流程如下图所示:

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

    从masterCandidates列表中选择,是将节点排序后选择最小的节点作为Master。但是 排序时使用自定义的比较函数 MasterCandidate::compare,早期的版本中 只是对节点 ID 进行排序,现在会优先把集群状态版本号高的节点放在 前面。

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

4.2 投票

    在ES中,发送投票就是发送加入集群(JoinRequest)请求。得票就 是申请加入该节点的请求的数量。 收集投票,进行统计,这里的投票就是加入它的连接数,当 节点检查收到的投票是否足够时,就是检查加入它的连接数是否足够, 其中会去掉没有Master资格节点的投票。

4.3 确认master

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

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

    如果其他节点被选为Master:

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

4.4 小结

将上述流程图拼接一番就是如下过程:
在这里插入图片描述

5 节点失效检测

    选主流程已执行完毕,Master身份已确认,非Master节 点已加入集群。 节点失效检测会监控节点是否离线,然后处理其中的异常。失效检 测是选主流程之后不可或缺的步骤,不执行失效检测可能会产生脑裂 (双主或多主)。
    我们需要启动两种失效探测器:

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

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

5.1 NodesFaultDetection

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

5.2 MasterFaultDetection

    探测Master离线的处理很简单,重新加入集群。本质上就是该节点 重新执行一遍选主的流程。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/939133
推荐阅读
相关标签
  

闽ICP备14008679号