es源码笔记-7.x 选主流程

es源码笔记-7.x 选主流程,第1张

Discovery模块负责发现集群中的节点,以及选择主节点。ES支持多种不同Discovery类型选择,内置的实现有两种:Zen Discovery和Coordinator,其他的包括公有云平台亚马逊的EC2、谷歌的GCE等。

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

ES 通过推迟选举,直到当前的 Master 失效来解决上述问题,只要当前主节点不挂掉,就不重新选主。但是容易产生脑裂(双主),为此,再通过“法定得票人数过半”解决脑裂问题

1、多数派原则:必须得到超过半数的选票才能成为master。

选出的leader一定拥有最新已提交数据:在raft中,数据更新的节点不会给数据旧的节点投选票,而当选需要多数派的选票,则当选人一定有最新已提交数据。在es中,version大的节点排序优先级高,同样用于保证这一点。

正确性论证:raft是一个被论证过正确性的算法,而ES的算法是一个没有经过论证的算法,只能在实践中发现问题,做bug fix,这是我认为最大的不同。

是否有选举周期term:raft引入了选举周期的概念,每轮选举term加1,保证了在同一个term下每个参与人只能投1票。ES在选举时没有term的概念,不能保证每轮每个节点只投一票。

选举的倾向性:raft中只要一个节点拥有最新的已提交的数据,则有机会选举成为master。在ES中,version相同时会按照NodeId排序,总是NodeId小的人优先级高。

2、Paxos算法

Paxos非常强大,尤其在什么时机,以及如何进行选举方面的灵活性比简单的Bully算法有很大的优势,因为在现实生活中,存在比网络连接异常更多的故障模式。但 Paxos 实现起来非常复杂

本篇只讨论内置的Zen Discovery

整体流程可以概括为:选举临时Master,如果本节点当选,则等待确立Master,如果其他节点当选,则尝试加入集群,然后启动节点失效探测器。

如果集群刚启动则参与选主,否则加入集群

org.elasticsearch.node.Node.start()

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

上面选择临时主节点非常简单,

首先需要判断当前候选者人数是否达到法定人数,否则选主失败。

取列表中的最小值,比较函数通过compareNodes实现,只是对节点 ID 进行排序

选举出的临时Master有两种情况:该临时Master是本节点或非本节点。

(2)超时(默认为30秒,可配置)后还没有满足数量的join请求,则选举失败,需要进行新一轮选举。

超时后直接return,当非临时节点加入集群不成功时,重新发起选主流程

org.elasticsearch.discovery.zen.ZenDiscovery.innerJoinCluster()

(3)成功后发布新的clusterState。

实现如下:

submitStateUpdateTask最终通过TaskBatcher# submitTasks来提交任务。执行任务并发布集群状态的总体过程在 MasterService#runTasks 方法中实现。

(2)向Master发送加入请求,并等待回复。超时时间默认为1分钟(可配置),如果遇到异常,则默认重试3次(可配置)。这个步骤在joinElectedMaster方法中实现。

最终当选的Master会先发布集群状态,才确认客户的join请求,因此,joinElectedMaster返回代表收到了join请求的确认,并且已经收到了集群状态。所以如果返回不成功,则重新发起选主流程

(3)检查收到的集群状态中的Master节点如果为空,或者当选的Master不是之前选择的节点,则重新选举。

1、es通过主从模式以及发现机制保证节点之间的负载均衡,但是es使用量的急剧增加暴露了很多问题,例如,Zen的minimum_master_nodes设置经常配置错误,这会使群集更容易出现裂脑和丢失数据的风险

2、7.x以上版本Coordinator提供了安全的亚秒级的master选举时间,而Zen可能要花几秒钟来选择一个新的master

3、es的master挂了,数据节点在这区间还能对外提供服务吗?

参考

Elasticsearch分布式一致性原理剖析

代码具体入口 org.elasticsearch.index.shard.IndexShard#prepareIndex

代码位置: org.elasticsearch.index.mapper.MetadataFieldMapper#preParse

下面只贴出 _id 的处理

ES 在转换 nested 结构的时候,比较有意思。

每个字段的填充入口在: org.elasticsearch.index.mapper.DocumentParser#innerParseObject

这里是一个递归调用的 *** 作。比较绕。

下面贴出来 _version 的处理

代码的入口: org.elasticsearch.index.mapper.VersionFieldMapper#postParse ,可以看看具体的实现。

bully算法是一个分布式系统中动态选择master节点的算法,进程号最大的非失效的节点将被选为master。

算法用三种消息类型:

当一个进程P从失败中恢复,或者接收到主节点失效信息,进程P将做以下事情:

我看的源码是5.6版本的。因此以下的解释都是依据5.6的源码来说的。

当master节点失效之后,各个节点find master的过程如下:

1)每个节点会ping配置文件中discovery.zen.ping.unicast.hosts的IP,找到所有存活的节点并过滤

2)找到非本身的active master

3)找到所有的可成为master的节点集合masterCandidates ,包含自己

4)如果activeMasters 为空,也就是说不存在活着的master节点,同时当前活着的节点满足配置中discovery.zen.minimum_master_nodes的数量,那么就从masterCandidates 挑出ID最小的节点,让其成为master节点。如果activeMasters 不为空,则从中选择最小的ID成为Master节点即可。

electMaster.electMaster方法和electMaster.tieBreakActiveMasters方法则都是从集合中选取最小节点的ID:

如果当前不存在active master,那么activeMasters 一定为空,则从masterCandidates 从选出id最小的节点即可。

如果当前存在active master,且当前节点不是active maste,那么从activeMasters 中选出id最小的节点。

如果当前存在active master,且当前节点是active maste,那么activeMasters 为空,从masterCandidates 中选出id最小的节点即自己。

在我的感觉中,当前active master的个数要么为空,要么为1,这边不知道为什么要用一个链表。。。为了防止脑裂情况出现吗??


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12089748.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-20
下一篇2023-05-20

发表评论

登录后才能评论

评论列表(0条)

    保存