赞
踩
elasticsearch的选举算法是基于Bully算法改造的。
Bully是Leader选举的基本算法之一。 它假定所有节点都有一个惟一的ID,该ID对节点进行排序。 任何时候的当前Leader都是参与集群的最高id节点。 该算法的优点是易于实现,但是,当拥有最大 id 的节点处于不稳定状态的场景下会有问题,例如 Master 负载过重而假死,集群拥有第二大id 的节点被选为 新主,这时原来的 Master 恢复,再次被选为新主,然后又假死…
elasticsearch 通过推迟选举直到当前的 Master 失效来解决上述问题。但是推迟选举是怎么个推迟法,本人搜索了很多论坛还是没有找到解释,求知道的大佬们指导一下,本人的理解是只要es的进程还在,就不会重新选举,直到master节点的es节点挂了为止。那什么叫挂了呢,个人认为是从节点是向Master节点的9300端口发送数据的不能得到返回时。
除此以外,用这种方式还容易产生脑裂,需要再通过法定得票人数过半的办法解决脑裂。
防止脑裂、防止数据丢失的极其重要的参数:
discovery.zen.minimum_master_nodes=(master_eligible_nodes)/2+1
这个参数的实际作用早已超越了其表面的含义,会用于至少以下多个重要时机的判断:
PUT /_cluster/settings
{
“persistent”: {
“discovery.zen.minimum_master_nodes”: 3
}
}
7 Master减容场景:缩容与扩容是完全相反的流程,需要先缩减Master节点,再把quorum数降低。修改Master以及集群相关的配置一定要非常谨慎!配置错误很有可能导致脑裂,甚至数据写坏、数据丢失等场景。
ZenDiscovery(默认)过程就是这样的:
1. 每个节点计算最低的已知节点ID,并向该节点发送领导投票。
2. 如果一个节点收到足够多的票数,并且该节点也为自己投票,那么它将扮演领导者的角色,开始发布集群状态。
3. 所有节点都会参数选举,并参与投票,但是,只有有资格成为 master 的节点的投票才有效(node.master为true)。
(就像皇上只在皇子中选一样。)
有多少选票赢得选举的定义就是所谓的法定人数。 在弹性搜索中,法定大小是一个可配置的参数。 (一般配置成:可以成为master节点数n/2+1)。
整体流程可以概括为:选举临时Master,如果本节点当选,等待确立Master,如果其他节点当选,等待加入Master,然后启动节点失效探测器。流程图如下所示:
临时Master的选举过程如下:
(1)“ping”所有节点,获取节点列表fullPingResponses,ping结果不 包含本节点,把本节点单独添加到fullPingResponses中。
(2)构建两个列表。 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资格的节点,添加到这个列表中。
(3)如果activeMasters为空,则从masterCandidates中选举,结果可 能选举成功,也可能选举失败。如果不为空,则从activeMasters中选择 最合适的作为Master。
整体流程如下图所示:
从masterCandidates中选主 与选主的具体细节实现封装在ElectMasterService类中,例如,判断 候选者是否足够,选择具体的节点作为Master等。 从masterCandidates中选主时,首先需要判断当前候选者人数是否达 到法定人数,否则选主失败。
从masterCandidates列表中选择,是将节点排序后选择最小的节点作为Master。但是 排序时使用自定义的比较函数 MasterCandidate::compare,早期的版本中 只是对节点 ID 进行排序,现在会优先把集群状态版本号高的节点放在 前面。
从activeMasters列表中选择,列表存储着集群当前存在活跃的Master,从这些已知的Master节点 中选择一个作为选举结果。选择过程非常简单,取列表中的最小值,比 较函数仍然通过compareNodes实现,activeMasters列表中的节点理论情 况下都是具备Master资格的。
在ES中,发送投票就是发送加入集群(JoinRequest)请求。得票就 是申请加入该节点的请求的数量。 收集投票,进行统计,这里的投票就是加入它的连接数,当 节点检查收到的投票是否足够时,就是检查加入它的连接数是否足够, 其中会去掉没有Master资格节点的投票。
选举出的临时Master有两种情况:该临时Master是本节点或非本节 点。为此单独处理。现在准备向其发送投票。
如果临时Master是本节点:
如果其他节点被选为Master:
将上述流程图拼接一番就是如下过程:
选主流程已执行完毕,Master身份已确认,非Master节 点已加入集群。 节点失效检测会监控节点是否离线,然后处理其中的异常。失效检 测是选主流程之后不可或缺的步骤,不执行失效检测可能会产生脑裂 (双主或多主)。
我们需要启动两种失效探测器:
NodesFaultDetection和MasterFaultDetection都是通过定期(默认为1秒)发送的ping请求探测节点是否正常的,当失败达到一定次数(默认 为3次),或者收到来自底层连接模块的节点离线通知时,开始处理节点离开事件。
检查当前集群总节点数是否达到法定节点数(过半),如果不 足,则会放弃 Master 身份,重新加入集群。为什么要这么做?设想下 面的场景,如下图所示。
假设有5台机器组成的集群产生网络分区,2台组成一组,另外3台 组成一组,产生分区前,原Master为Node1。此时3台一组的节点会重新 选举并成功选取Noded3作为Master,会不会产生双主? NodesFaultDetection就是为了避免上述场景下产生双主。
主节点在探测到节点离线的事件处理中,如果发现当前集群节点数 量不足法定人数,则放弃Master身份,从而避免产生双主
探测Master离线的处理很简单,重新加入集群。本质上就是该节点 重新执行一遍选主的流程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。