elasticsearch源码分析之discovery(七)

elasticsearch源码分析---discovery模块 根据guice的注册绑定机制,discovery的绑定顺序是这样的: InternalNode中添加DiscoveryModule: modules.add(new DiscoveryModule(settings)); DiscoveryModule中创建了LocalDiscoveryModule(不分析)或者ZenDiscoveryModule: public Iterable s 阅读详情

Discovery模块概述

elasticsearch中的Discover模块,这个模块主要是发现模块负责发现集群中的节点,以及选取主节点。用作处理elasticsearch中的集群问题,是elasticsearch中比较复杂的一个模块。
discovery有几类:

  • Azure discovery(类似于多播),它可作为插件使用。
  • EC2 discovery,作为插件使用。
  • Google Compute Engine (GCE) discovery (类似于多播),它可作为插件使用。
  • zenDiscovery是elasticsearch的内置并且默认的discovery模块。 它提供unicast发现,并且扩展到支持云环境和其他形式的发现。

这里我们只分析zenDiscovery。

Discovery子模块

ZenDiscover其实是由一些其他的模块配合而成的,比如node之间的通信就是用的transport模块。ZenDiscover可以分为以下几个子模块:

Ping

这是一个节点使用发现机制来查找其他节点的过程。

Unicast

通过配置discovery.zen.ping.unicast对列表中的node单播。
单播发现需要使用的主机列表作为传播的路由器,它使用discovery.zen.ping.unicast前缀提供以下设置:

可以是数组设置或逗号分隔设置。
每个值的格式应为host:port或host(其中,port默认为9300)。 请注意,IPv6主机必须加括号。 默认为127.0.0.1,[:: 1]

unicast discovery用transport模块来执行发现。

Master Election

用作Master的选举;集群的主节点被选举或加入是ping过程的一部分。这是自动完成的。
当主节点停止或遇到问题时,群集节点再次开始ping过程,并选择一个新的主节点。这轮ping还用作对(部分)网络故障的保护,其中节点可能不正当地认为主节点已经故障。在这种情况下,节点将简单地从其他节点听到关于当前活动的主机的信息。
discovery.zen.minimum_master_nodes设置需要加入新选择的主节点的主合格节点的最小数量,以便选择完成,并且选择的节点成为masternode。相同的设置控制应作为任何活动集群的一部分的活动主机合格节点的最小数量。如果不满足此要求,活动主节点将退出,并且将开始新的主节点选择。

Fault Delection

用ping的方式来确定node是否在集群里面,有两个fault detection进程运行。 第一个nodesFD是由master去ping所有其他集群中的节点并验证他们是活着的。 第二个masterFD是每个节点ping到master以验证其是否仍然活着或者需要启动选举过程。
有如下设置使用discovery.zen.fd前缀控制fault detection过程:

ping_interval #节点被ping的频率,默认为1s。
ping_timeout #等待ping响应的时间长度,默认为30秒。
ping_retries #ping失败重试次数,默认为3。

Cluster state updates

这个只在master node上有效,用于向其他node发布集群的状态信息。
master节点是集群中可以更改集群状态的唯一节点。 master一次处理一个群集状态更新,修改更新并将更新的群集状态发布到群集中的所有其他节点。 每个节点接收发布过来的消息,更新其本地的集群状态,并且响应给主节点。主节点会等待所有节点的响应,直到一个超时时间,在这之前后面的更新请求都会排在一个队列中。 discovery.zen.publish_timeout默认设置为30秒,可以通过集群更新设置api动态更改。

No master block

要使集群完全可操作,它必须具有活动的master节点,并且运行的主节点合格节点数必须满足discovery.zen.minimum_master_nodes设置(如果设置)。
discovery.zen.no_master_block设置控制当没有活动主机时应拒绝哪些操作。

discovery.zen.no_master_block设置有两个有效选项:

all
节点上的所有操作读和写操作都将被拒绝。这也适用于api集群状态读取或写入操作,如get索引设置,put映射和集群状态api。

write(默认值)
写操作将被拒绝。根据最后一个已知的集群配置,读取操作将成功。这可能导致过时数据的部分读取,因为此节点可能与群集的其余部分隔离。
discovery.zen.no_master_block设置不适用于基于节点的api(例如cluster stats、 node info and node stats)。对这些API的请求不会被阻止,并且可以在任何可用节点上运行。

ZenDiscovery代码分析

构造函数

在ZenDiscovery构造函数中,初始化一些基本的服务接口和关键参数:

  • pingTimeout: 取自discovery.zen.ping_timeout(默认为3s)允许调整选举时间来处理网络慢或拥塞的情况(更高的值确保更少的失败机会)。
  • joinTimeout:取自discovery.zen.join_timeout(默认值为ping超时的20倍)。当一个新的node加入集群时,将会发个join的request到master,这个request的timeout即joinTimeout。
  • joinRetryAttempts:join重试的次数,默认为3次。
  • joinRetryDelay:重试的间隔,默认为100ms。
  • maxPingsFromAnotherMaster:容忍其他master发出的,在强制其他或是本地master rejoin之前的次数。
  • masterElectionWaitForJoinsTimeout: master选举时等待join的timeout,默认是joinTimeout的一半。
  • masterElectionFilterClientNodes:取自discovery.zen.master_election.filter_client为true(默认值为true)
    如果为true,则在主选举期间忽略来自客户机节点(节点node.client为true,或node.data和node.master都为false的节点)的ping。
  • masterElectionFilterDataNodes: 取自discovery.zen.master_election.filter_data(默认值为false),如果为true,则在主选举期间将忽略来自非主节点数据节点(node.data=true,node.master=false)的ping。在主选举期间总是观察到来自master节点的ping。

joinRetryAttempts和maxPingsFromAnotherMaster必须大于等于1.
构造方法

运行

ZenDiscovery的运行即几个子模块的运行

joinThreadControl

首先要将自己加入集群,使用joinThreadControl

1、首先是findMaster,findMaster通过pingService来实现,在这里我们只探讨unicast的ping的方式,主要的实现在sendPings这个方法里面,让我们来详细看看这个方法是怎么ping的。
确定需要ping的目标:

  • 第一部分是其实是由clusterService.state().nodes()而得来,也就是拥有同一cluster.name的这些node
  • 第二部分是hostsProviders自动生成的hosts列表(此处怎么来的还不清楚)
  • 第三部分是所以可能作为master的node
  • 第四部分是discovery.zen.ping.unicast.hosts配置的列表(主要在这里)

这里写图片描述

2、对nodesToPingSet排序,这个排序的依据是根据可能成为master的概率来的。将master node排在前面,data node排在后面;然后把第四部分的hosts加在最前面(人工配置的master,如果有的话肯定从中选择),最后在加入刚才排序的集合,这样组成新的集合nodesToPing。

3、分别对nodesToPing中的node发送ping,如果transport连接在,将会发送一个ping request到目标node,发送的逻辑是调用了TransportService,最终调用NettyTansport,tranport模块参照http://blog.youkuaiyun.com/thomas0yang/article/details/52355798。如果transport连接不在了,会先connectToNode建立连接,然后再发送ping request。

// if we find on the disco nodes a matching node by address, we are going to restore the connection
// anyhow down the line if its not connected…
// if we can’t resolve the node, we don’t know and we have to clean up after pinging. We do have
// to make sure we don’t disconnect a true node which was temporarily removed from the DiscoveryNodes
// but will be added again during the pinging. We therefore create a new temporary node

这一段解释没有看懂。。。

4、对ping之后有响应结果的集合进行过滤筛选,过滤逻辑参照上文中masterElectionFilterClientNodes和masterElectionFilterDataNodes解释。
pingMasters,即ping各个节点之后返回的各节点元数据中存储的master节点,在pingMasters列表中不能包括本地节点,否则我们可能在ZenDiscovery中没有检查其他节点,直接选举自己#innerJoinCluster(),造成脑裂。
这里写图片描述

5、然后创建两个node列表,一个是activeNodes,表示所有active的node,joinedOnceActiveNodes,前者后者表示集群中之前就存在的node。

6、 如果从之前的ping中没有发现master,表示要重新选举了;首先判断active的master node是否大于配置中的minimumMasterNodes,不然是选举不了master的。如果满足minMaster,会优先从joinedOnceActiveNodes中选举出master;若选不出才会从activeNodes中去选举。选举的逻辑比较简单, 先排序,在排序时会remove掉不能作为master的node,排序完后将第一个作为master。

7、如果pingMasters不为空,表示已经有选举出的master了,但是还在pingMasters列表中进行一次选举,得到master。官方注解:lets tie break between discovered nodes。但是此时pingMasters中如果不一个master,则会出现了脑裂。

在加入集群后,node就根据自己的角色,做不同的事情。

master

如果当前node是master,会先等待来足够的有资格成为master的节点join以完成主选举(waitToBeElectedAsMaster方法), 如果是则会通过ClusterState更新任务变为主节点。
更新任务参照这里写图片描述
真正发布状态参照InternalClusterService.UpdateTask类的run方法,
这里写图片描述
然后会启动nodesFD,nodesFD启动一个schedulethreadPool.schedule(TimeValue.timeValueMillis(0), ThreadPool.Names.SAME, fd);去ping其他的node,相当于heartbeat,如果检测失败会被踢出集群nodesFD.remove(node, NodeFD.this)。
这里写图片描述
(上面一些代码比较凌乱,有待深入研究)

如果当前node不是master,会向master发出一个join的request,注意这里并不会开启一个master fault detection;因为这一部分在processNextPendingClusterState中实现。

publishClusterState

这里写图片描述

elasticsearch默认发送state采用diff的方式,当然你也可以通过配置来设置discovery.zen.publish_diff.enable是否使用diff。
ClusterState表示集群的当前状态。具体参照elasticsearch源码分析之Gateway(六)

集群状态对象是不可变的,除了{@link RoutingNodes}结构和和集群状态{@link #status},前者是根据{@link RoutingTable}的需求构建的,后者是在集群状态发布和应用处理期间更新。集群状态只能在主节点上更新。所有更新都由单个线程执行,由{@link InternalClusterService}控制。每次更新后,{@link DiscoveryService#publish}方法会向群集中的所有其他节点发布群集状态的新版本。实际的发布机制委托给{@link Discovery#publish}方法,并取决于发现的类型。例如,对于本地发现,它由{@link LocalDiscovery#publish} 方法。在Zen发现中,它在{@link PublishClusterStateAction#publish}方法中处理。发布机制可以被其他发现覆盖。

集群状态实现{@link Diffable}接口,以支持发布集群状态差异,而不是每次更改时的整个状态。如果此节点存在于集群状态的先前版本中,则发布机制应仅向节点发送差异。如果一个节点不存在于以前版本的集群状态,这样的节点不太可能有以前的集群状态版本,应该发送完整版本。为了确保差异应用于集群状态的正确版本,每个集群状态版本更新将生成{@link #stateUUID}唯一标识该版本的状态。此uuid由{@link ClusterStateDiff#apply}方法验证,以确保应用正确的差异。如果uuids不匹配,则{@link ClusterStateDiff#apply}方法会抛出{@link IncompatibleClusterStateVersionException},这将导致向生成此异常的节点发送一个完整版本的集群状态。

发送ClusterChangedEvent,这个类持有两个clusterstate

private final ClusterState previousState;
private final ClusterState state;

这里写图片描述

publish最终会调用tranportservice方法,发送数据。具体参照elasticsearch源码分析之Transport(五)

FaultDetection

MasterFaultDetection

MasterFaultDetection是每个节点ping到master,进行错误检测。
启动时候连接masternode,并按照一定频率ping master。
这里写图片描述
master接收到masterping,进行一系列校验,返回空response
这里写图片描述
node端接收到response,
这里写图片描述
如检测到master失效,则发布master失效通知,启动重新选举
这里写图片描述

NodesFaultDetection

如果本node是master,而它又接收到来自其他node的再来看看NodesFaultDetection,则集群里有两个master,一般称之为“脑裂”。遇到这种情况时,node会比较自己的version和另外master的version;如果比别人的小,就会stop掉自己的nodesFD和masterFD,然后rejoin进集群,开始joinThreadControl干的那些事儿。如果version比别人的大,那么当前node仍然是master,它会向另一个master发出rejoin指令。
这里写图片描述

终于完了,异步跟踪查看代码比较累。
Discover的内容比较多。这个模块主要的作用是维护这个集群的状态,并负责state的下发,master的选举,配置的更新等等,是elasticsearch中较为核心的一个模块。

最后,感谢http://www.opscoder.info/es_discover.html

【ElasticSearch】Es 源码之 Discovery DiscoveryModule 源码解读 1.概述 根据启动流程 【ElasticSearch】Es 启动流程源码分析 在Node初始化的时候将会初始化DiscoveryModule logger.info("初始化 DiscoveryModule "); final DiscoveryModule discoveryModule = new DiscoveryModule(settings, threadPool, transportService, namedWriteableRegistry, networkService, cl 阅读详情

相关推荐

【ElasticSearch】Es 启动流程 源码分析

1. 概述 在博客 【ElasticSearch】Es 启动流程 初始化流程 源码分析 中我们对集群的初始化进行了一次分析,下面开始对启动方法进行分析。 2. start方法 在一系列检测完成之后,实例化Node并start。由于ES采用了模块化的架构思路,因此Node的start出乎意料的简洁: public Node start() throws NodeValidationException { if (!lifecycle.moveToStarted()) {

九师兄 560

Elastic:如何使用 Elastic 机器学习来侦测异常(二)

这篇文章是上一篇文章 “Elastic:如何使用 Elastic 机器学习来侦测异常(一)” 的续篇。在这篇文章中,我将展示如何创建一个 multi-metric 的任务。我将使用另外一个 Sample dataset。 添加 eCommerce 数据集 打开 Kibana: 这样我们就在 Elasticsearch 中创建了一个叫做kibana_sample_data_ecommerce 的索引。 我们可以在 Discover 中查看这个索引的所有字段: 创建 Mu...

Elastic 中国社区官方博客 3793

【ElasticSearch】Es 源码之 GatewayMetaState 源码解读

1.概述 根据启动流程 【ElasticSearch】Es 启动流程源码分析 在Node初始化的时候将会初始化GatewayMetaState logger.info("初始化 GatewayMetaState "); final GatewayMetaState gatewayMetaState = new GatewayMetaState(); 在启动时加载(可能升级)集群元数据,并持久化存储集群元数据以备将来重新启动。 启动时,确保此版本与存储在磁盘上的状态兼容,并在必要时执行状态升级。请注意

九师兄 293

发现Accesslog中的秘密By Elasticsearch7.5 + Kibana7.5之Discover

Kibana7.5之DiscoverDiscover Discover

jinhong618的专栏 648

CentOS校园网Web Portal认证自动化实战

Web Portal认证是一种基于HTTP重定向与表单提交的强制网络准入机制,其原理是网关劫持未认证流量并跳转至登录页,验证通过后通过Cookie维持会话授权。该技术广泛应用于高校、机场、酒店等场景,核心价值在于细粒度访问控制与用户身份绑定。典型应用包括Linux命令行环境下的校园网接入、无GUI设备的自动联网、以及实验室集群的集中认证管理。本文聚焦CentOS系统,深入解析curl、cookie持久化、动态表单参数提取等关键技术环节,提供可调试、可复现、可工程化的完整认证流水线。

weixin_30522983的博客 265

LNA设计学习心得记录----MOS管的选取

LNA设计学习心得---MOS管的选取仿真

weixin_40359668的博客 6127

Discover - Elastic通过trace抓取信息到EXCEL

通过python爬取Discover - Elastic的异常信息

xiaobai_july的博客 1358

FEniCS学习笔记01:centos7下通过conda安装FEniCSx0.7

2023年版本的Fenicsx0.7,官网推荐使用conda命令安装集成好的Python包,因此我们的安装思路是先安装Anaconda,再按照官网步骤安装Fenics。

huahua_xiao的博客 5057

elasticsearch Discovery 发现模块学习

发现模块和集群的形成 目标 发现节点 Master选举 组成集群,在Master信息发生变化时及时更新。 故障检测 细分为几个子模块 Discovery发现模块 Discover是在集群Master节点未知时,互相发现对方的过程,例如新节点的加入或是先前的主节点宕机,如果一个节点不满足Master资格,则它将继续发现,直到发现了选定的主节点为止,其中,重试配置的属性为:discover...

独行侠梦的博客 1478

(篇八)C语言在母串删子串、输入位置截取子串

文章目录一、字符串二、删除指定的字符三、从母串中截取子串四、输入位置截取子串 本篇主要介绍C语言字符串中的相关操作,然后分析两个C语言实例——在母串中指定删除子串、在母串中截取子串 一、字符串 了解C 语言的都知道,C语言中没有字符串类型,所以C语言是用字符串常量、字符指针、字符数组来表示字符串。这些字符串都是以 NULL、’\0’或者ASCII==0来结尾。说白了就是一个个字符组成一串有序序列,...

Viewinfinitely的博客 1512

记一次wireshark抓取QQ好友IP和火绒抓取微信IP

事情是这样的,,上个周,手机离奇的被盗,但没有关机,为了找回手机,粗学了一手QQ抓ip的手段。 这里我就直接做个演示,解析关键的点。 三种思路i. wireshark 抓取手机在线IPii 火绒抓取 微信在线接听IPiii 火绒抓取 微信在线不接听IP i. wireshark 抓取手机在线IP wireshark抓好友QQ的ip要求和对方打语音的时候要手机在线。 这里说一下,打语音和视频是直接能和对方建立连接,如果发文件,是直接发给腾讯的,抓不到包。 1.打开wireshark,通过电脑Tim给对方打语音

qq_29437513的博客 1万+

Elasticsearch搜索引擎该怎么使用,这篇文章彻底讲透(荣耀典藏版)

什么是Elasticsearch?Elasticsearch该怎么使用?这篇文章带你认识Elasticsearch

人生若只初相见@的博客 1万+

Codex 接入自定义大模型终极教程:插件解锁、会话管理、国产模型一键搞定

🚀 Codex 默认只能使用 OpenAI 官方模型?这篇文章带你从零接入 DeepSeek、通义千问、GLM 等国产大模型,并彻底解锁插件、会话删除、多模型切换等隐藏功能。配置原理、常见坑点、傻瓜式增强工具分享,小白也能轻松上手!🔥

XiaoqiangClub的博客 3152

Spark Core读取ES的分区问题分析

ES也是比较火热,在日志数据分析,规则分析等确实很方便,说实话用es stack 浪尖觉得可以解决很多公司的数据分析需求。极客时间下周一要上线新的ES课程,有需要的暂时别...

大数据星球-浪尖 1723

深入解析 Multi-Agent 协同决策机制与架构设计

让我们从一些基础定义开始,为后续的讨论建立共同的语言。在计算机科学和人工智能领域,智能体(Agent)是指一个能够感知环境、做出决策并执行动作的实体。智能体是任何可以通过传感器感知环境,并通过执行器作用于该环境的事物。atπstat​πst​sts_tst​是时刻ttt的环境状态(或智能体的观测)π\piπ是智能体的策略(Policy),即从状态到动作的映射ata_tat​是智能体在时刻ttt选择执行的动作多智能体系统(MAS)

AI天才研究院 542

Python经典编程习题100例:第32例:相反顺序输出列表

不要自卑,去提升实力 互联网行业谁技术牛谁是爹 如果文章可以带给你能量,那是最好的事!请相信自己 加油o~ 本人初学Python,只为熟悉语法编写,大神请勿理会 点击下面链接 Python经典编程100例习题汇总 题目描述: 按相反的顺序输出列表的值。 解题思路: > 利用reverse函数逆序 代码: arr=['f','g','e','b'] print(arr) arr.reverse() print(arr) ...

优快云 精品推荐 1417

Spark Core读取 ES 数据分区问题分析

ES也是比较火热,在日志数据分析,规则分析等确实很方便,说实话用es stack可以解决很多公司的数据分析需求。 Spark 分析ES的数据,生成的RDD分区数跟什么有关系呢? 稍微猜测一下就能想到跟分片数有关,但是具体是什么关系呢? 可想的具体关系可能是以下两种: 1).就像KafkaRDD的分区与kafka topic分区数的关系一样,一对一。 2).ES支持游标查询,那么是不...

yang灬仔 1294

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Prometheus 实战于源码分析之discovery

prometheus与时俱进在现在各种容器管理平台流行的当下,能够对各种容器管理平台进行数据采集和处理,并且能够自动发现监控对象,这个就是今天要说的discovery。他是一个资源发现的组件,能够根据资源变化调整监控对象。目前已经支持的discovery主要有DNS、kubernetes、marathon、zk、consul、file等,我们先从这个kubernetes的服务发现开始讲解吧 先是创

柳清风的专栏 1万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

zookeeper源码分析之事务请求处理

LeaderRequestProcessor->PrepRequestProcessor->ProposalRequestProcessor(含有SyncRequestProcessor的成员变量,processRequest中先调用下一个,再调用SyncRequestProcessor)->CommitProcessor->ToBeAppliedRequestProcessor->FinalRequestProcessor.1.1如果是leader启动的时候会倒序初始化下面6个processor,

研究源码的最底层,只持有正确的仓位 987

elasticSearch6源码分析(12)DiscoveryModule

1.DiscoveryModule概述 /** * A module for loading classes for node discovery. */ 2.discovery  The discovery module is responsible for discovering nodes within a cluster, as well as electing ...

weixin_34162401的博客 140

Elastic Stack日志分析(十二)- Elasticsearch Master选举流程详解

Elasticsearch选举Master算法,Elasticsearch Master选举流程详解,Elasticsearch Master选举时间前提

程序园@大Null 2263

elasticsearch源码分析-02选举主节点

NodesFaultDetection运行在master节点,master也是定时发送心跳ping请求给非master节点,如果发送失败则先重试,重试达到一定次数调用notifyNodeFailure,如果返回连接错误则调用handleTransportDisconnect(node)如果选择的master节点是本节点加入的节点则设置选举结束。首先会比较两个候选节点的集群状态版本信息,如果版本信息比较新则排在前面,如果版本号相同则需要比较两个节点的节点id,然后选择排在最前面的一个节点为master。

GeekerJava的博客 1193

elasticsearch 是如何实现 master 选举的

ElasticSearch 的选主是 ZenDiscovery 模块负责,源码分析将首发在。 https://gitee.com/rodert/JavaPub 对所有可以成为 Master 的节点(node.master: true)根据 nodeId 排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是 Master 节点。 如果对某个节点的投票数达到一定的值(可以成为master节点数n/2+1)并且该节点自己也选举自己,那这个节点就是master。否则重新.

JavaPub 2173

ES 源代码阅读(一)

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34288121的博客 489
上一篇: 生产环境elasticsearch的配置建议
下一篇: elasticsearch的Doc Values 和 Fielddata
thomas0yang
博客等级 码龄16年 206粉丝 65原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值