ES源码二:集群启动过程

命令行参数解析

Elasticsearch:
image.png
在main里面创建了Elasticsearch实例,然后调用了main方法,这个main方法最终会调用到父类Command的main方法
image.png

这里做了几件事:

  1. 注册一个 ShutdownHook,其作用就是在系统关闭的时候捕获IOException并且进行输出

image.png

  1. 解析命令行参数

image.png

  1. 加载多个路径:data、home、logs,这里会调用到子类EnvironmentAwareCommand的execute方法,将配置解析成hashmap,并且确认 es.path.data、es.path.home、es.path.logs 这几个路径设置的存在,最后调用createEnv方法加载elasticsearch.yml配置文件,在调用Elasticsearch.execute方法

image.png

  1. 加载elasticsearch.yml配置文件

createEnv 函数最终调用了 InternalSettingsPreparer.prepareEnvironment 来加载 elasticsearch.yml 配置文件,并且创建了 command 运行的环境:Environment 对象

  1. 验证配置

image.png

总结一下第一阶段:解析命令行参数并且验证配置

资源检查和本地资源初始化

阶段二主要是在Bootstrap类中进行的,我们进入到Bootstrap.init方法中看
image.png
这个方法特别长,主要做了这样几件事:

  1. 创建BootStrap对象

image.png

  1. 加载elasticsearch.keystore 安全配置:在ES运行后,在config目录会生成一个elasticsearch.keystore文件,这个文件是用来保存一些敏感配置的。因为ES大多数配置都是明文保存的,但是像X-Pack中的security配置需要进行加密保存,所以这些配置信息就是保存到elasticsearch.keystore中。image.pngimage.png
  2. 创建一个新的Environment:根据保存初始化配置的initialEnv和安全配置keystore调用createEnvironment(最终调用prepareEnvironment方法)重新创建一个运行ES必须的环境

image.png

  1. 设置节点名称:这里设置节点的名字,可以在后续的日志输出中使用,否则只要只要ID可用就会使用节点ID(节点ID可读性不好)

image.png

  1. 加载log4j2配置:会加载log4j2.properties文件中的相关配置,然后配置log4j的属性。

image.png

  1. 创建pid文件

image.png

  1. 检查Lucene jar:通过版本号来检查lucene是否被替换掉了,如果被替换无法被启动

image.png

  1. 为创建Node对象实例做准备工作:通过调用INSTANCE.setup(true, environment)为创建Node实例对象做一些准备工作,下面几步我们进入到INSTANCE.setup(true, environment)

image.png
image.png

  1. 为给定模块生成控制器守护程序:尝试为每个模块(modules目录下的模块)生成native控制器守护进程的。

image.png

  1. 初始化本地资源:

image.png
image.png
本地资源初始化主要包括:

  • 不能以root运行
  • 尝试启动系统调用过滤器
  • 尝试调用mlockall,mlockall会将进程使用的部分或者全部的地址空间都锁定在物理内存中,防止其被交换到swap空间
  • 如果是运行在window的话,关闭事件的监听器
  • 尝试设置最大线程数、最大虚拟内存、最大文件size
  • 为lucene设置一个随机的seed

除了调用initializeNatives方法进行本地资源初始化,还调用initializeProbes() 进行初始化探针操作,主要用于操作系统负载监控、jvm 信息获取、进程相关信息获取。
image.png

  1. 注册关闭资源的 ShutdownHook

image.png

  1. 通过调用 JarHell.checkJarHell 检查是否有重复的类。

image.png

  1. 在Debug 模式下以 ifconfig 格式输出网络信息

image.png

  1. 加载安全管理器,进行权限认证:通过调用Security.configure 函数进行安全管理器加载,进行权限认证操作:

image.png

  1. 创建Node实例对象:根据加载的运行环境创建Node实例,也快要进入第三个阶段了

image.png

  1. 启动Node节点:回到了之前set up的地方,然后调用start方法,进行node节点的启动

image.png

节点实例启动

节点创建

之前只是简单的看了一下Node的创建,再回顾一下:
image.png
后续在构造方法里面一共做了这样几件事:

  1. 设置节点的生命周期:将生命周期设置为INITIALIZED,此时节点正处于初始化状态

image.png
image.png

  1. 各种信息的打印:

image.png

  1. 创建插件服务:主要是加载modules目录中的模块和加载plugins目录中已经安装的插件

image.png

  1. 设置格外的节点角色:

image.png

  1. 创建NodeEnvironment:NodeEnvironment实例话的过程中会生成Node ID,最后此处打印节点相关的信息,需要注意的是,此处会通过 Environment.assertEquivalent 函数来保证启动过程中配置没有被更改

image.png

  1. 创建线程池:

image.png
ES线程池的实现封装在ThreadPool中。ThreadPool中定义了4种线程池类型:
image.png

  • direct:执行器不支持关闭的线程
  • fixed:拥有固定线程的线程池,当一个任务无法分配一条线程时会被排队
  • fixed_auto_queue_size:和fixed类似,但是任务队列会根据 Little’s Law 自动调整。8.0 后将被移除。
  • scaling, 线程池中线程的数量可变,线程的数量在 core 和 max 间变化,使用 keep_alive 参数可以控制线程在线程池中的空闲时间。

ThreadPool中创建了多个线程池,主要有以下几种:
image.png

  1. 创建NodeClient实例:NodeClient执行本地的action的。

image.png

action的类型定义在ActionType:
image.png

  1. 创建各个模块和服务:各个模块和服务的创建

image.png

  1. **绑定对应的对象到Guice:将实例化的对象绑定要ModulesBuilder中,最后调用 modules.createInjector 创建 injector(注入器)。ES 用到了 **Guice这个谷歌提供的轻量级 IOC 库,bind 和 createInjector 是其提供的基本功能。

image.png
image.png
image.png

  1. 初始化HTTP Handler

image.png

后续就是节点启动的流程了

节点启动

Node.start主要负责启动各个生命周期组件(LifecycleComponent)和从Guice(也就是injector)中获取需要启动的服务类实例,然后调用它们的start方法
image.png
并且后面是一堆server要启动:
image.png

总结一下:

  1. 启动各个生命周期组件和服务,一些重点的服务如下:
服务简介
IndicesService负责索引管理,如创建、删除等操作。
IndicesClusterStateService负责根据各种集群索引状态信息进行相应的操作,如创建或者恢复索引(这些实际的操作会交给具体的模块实现)等。
SnapshotsService负责创建快照,在执行快照创建和删除的时候,所有的执行步骤都在主节点上=进行。
SnapshotShardsService此服务在 data node 上运行,并且控制此节点上运行中的分片快照。其负责开启和停止分片级别的快照。
RepositoriesService负责维护节点快照存储仓库和提供对存储仓库的访问。
SearchService提供搜索支持的服务。
ClusterService集群管理服务,负责管理集群状态、处理集群任务、发布集群状态等。
FsHealthService文件系统健康检查服务。通过创建一个临时文件来检查文件系统是否可写。
MonitorService负责提供操作系统、进程、JVM、文件系统级别的监控服务
NodeConnectionsService该组件负责维护从该节点到集群状态中列出的所有节点的连接,并在节点从集群状态中删除后断开与节点的连接。并且会定期检查所有链接是否在打开状态,并且在需要的时候恢复它们。需要注意的是此组件不负责移除节点!
GatewayService网关服务,负责集群元数据的持久化和恢复。
Discovery节点发现模块是一个可插拔的模块,其负责发现集群中其他的节点,发布集群状态到所有节点,选举主节点和发布集群状态变更事件。
PeerRecoverySourceService负责处理对等分片的恢复请求,并且开启从这个源分片到目标分片的恢复流程。
TransportService负责节点间数据同步。
HttpServerTransport提供 REST 接口服务。
  1. 调用ClusterService.setNodeConnectionService将NodeConnectionService绑定到ClusterService中去
  2. 调用acceptIncomingRequests 尝试接收请求。
  3. 调用discovery.startInitialJoin 开始进行加入集群的循环
  4. 开启线程去检查是否已经加入集群
  5. HttpServerTransport,并且绑定监听地址,接收 REST 请求

4.集群启动流程

  1. Master 选举

根据前面的内容可知,Master 对集群的重要性,所以集群中多个节点启动后首要的任务是选举出一个 Master,有了 Master 后续的集群启动操作将由 Master 主导。

  1. 选择集群元数据

在 Master 被选举出来后,其首要任务就是要选择出集群的元数据信息,这部分的工作主要在 Gateway 模块中处理。Master 会向已经加入到集群的所有节点获取各种的元数据信息,然后选择出版本号最新的那个作为集群的元数据,并向所有节点进行广播。

  1. Allocation

在 allocation 过程中将会选择 shard 级别的元数据信息,并且构建内容路由表。在集群启动的时候,所有的 shard 都是未分配的,allocation 会决定哪个 shard 被分配到哪个节点,并且把这个关系记录下来写入到内容路由表。
我们知道 ES 的分片分为主分片和副分片,所以在分配的时候会先选择出主分片,然后再选择出副分配。

  1. 索引恢复(recovery )

为了保证数据的可靠性,在启动的时候主分片需要执行 recovery 流程来恢复没有来得及刷盘的数据。而副分片除了要恢复没有刷盘的数据外,还要恢复主分片已经写入但是副分片还没有写入的数据来保证数据的一致性。
集群的启动主要就是上述的几大流程,经过这些流程后,一般来说集群就可以提供对外的服务了。

5.总结

通过 Elasticsearch 这个类,系统进行了命令行参数解析与配置加载。通过 Bootstrap 类进行了资源检查与本地资源初始化。最后实例化了 Node 类,其负责加载各个模块和插件、创建线程池、创建 keepalive 线程等工作,在 Node.start 方法中获取了各个服务的实例并且调用它们的 start 方法。
image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/624941.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测算法——YOLOV9——算法详解

一、主要贡献 深度网络输入数据在逐层进行特征提取和空间变换时,会丢失大量的信息。针对 信息丢失问题,研究问题如下: 1)从可逆功能的角度对现有深度神经网络架构进行了理论分析,解释了许多过去难以解释的现象&#xf…

【网络编程】如何创建一个自己的并发服务器?

hello !大家好呀! 欢迎大家来到我的网络编程系列之如何创建一个自己的并发服务器,在这篇文章中,你将会学习到在Linux内核中如何创建一个自己的并发服务器,并且我会给出源码进行剖析,以及手绘UML图来帮助大家…

3D目标检测实用技巧(三)- 生成虚拟点

一、引言 本次参考的是VirConv生成虚拟点的方法: VirConv/tools/PENet at master hailanyi/VirConv GitHubVirtual Sparse Convolution for Multimodal 3D Object Detection - VirConv/tools/PENet at master hailanyi/VirConvhttps://github.com/hailanyi/Vir…

手写spring IOC底层源码来模拟spring如何利用多级缓存解决循环依赖的问题

在文章开始之前,先来看一张spring IOC加载过程的脑图吧 Spring IOC的加载过程 首先,当我们去new了一个applicationContext,它底层呢就会把我们配置的bean进行扫描,然后创建成一个一个的beanDefinition放在我们的beanDefinitionMap中,此时就有了一切创造bean的原料信…

计算机网络:MAC地址 IP地址 ARP协议

计算机网络:MAC地址 & IP地址 & ARP协议 MAC地址IP地址ARP协议 MAC地址 如果两台主机通过一条链路通信,它们不需要使用地址就可以通信,因为连接在信道上的主机只有他们两个。换句话说,使用点对点信道的数据链路层不需要使…

宝剑锋从磨砺出,透视雀巢咖啡品牌焕新与产品升级的想象力

自1989年进入中国市场以来,陪伴着国内咖啡行业由启蒙期走向兴盛期的雀巢咖啡,始终坚持以消费者高品质、个性化需求为本位,在保有独特性的基础上持续创新,实现了从无到有的攻克与突破。 近日,深耕中国三十六载的雀巢咖…

2024蓝桥杯每日一题(组合计数)

备战2024年蓝桥杯 -- 每日一题 Python大学A组 试题一:计算系数 试题二:求组合数1 试题三:求组合数2 试题四:杨辉三角形 试题一:计算系数 【题目描述】 给定一个多项式 (axby)k,请…

数字革命的先锋:Web3对社会的影响

引言 在信息技术飞速发展的当下,Web3作为一个新兴的互联网模式,正在逐渐改变我们的生活方式、商业模式和社会结构。本文将深入探讨Web3的核心特点、它在各个领域中的应用以及对社会产生的深远影响。 1. Web3的核心特点 1.1 去中心化 Web3强调去中心化…

电脑不能上网,宽带调制解调器出现问题如何处理

目录 一、问题说明 二、解决方案 一、问题说明 内网的设备能互联,内网的各个设备无法连外网。 电脑在检测网络时,出现以下提示: 二、解决方案 首先重启光猫(我们是电信宽带)。 如果还是有问题,再重启…

【Blockchain】连接智能合约与现实世界的桥梁Chainlink

去中心化预言机试图实现依赖因果关系而不是个人关系的去信任和确定性结果。它以与区块链网络相同的方式实现这些结果,即在许多网络参与者之间分配信任。通过利用许多不同的数据源并实施不受单个实体控制的预言机系统,去中心化的预言机网络有可能为智能合…

第十五届蓝桥杯题解-数字接龙

题意:经过所有格子,并且不能进行交叉,走的下一个格子必须是当前格子值1%k,输出路径最小的那一条(有8个方向,一会粘图) 思路:按照8个方向设置偏移量进行dfs,第一个到达终…

Achronix FPGA增加对Bluespec提供的基于Linux的RISC-V软处理器的支持,以实现可扩展数据处理

Bluespec支持加速器功能的RISC-V处理器将Achronix的FPGA转化为可编程SoC 2024年4月——高性能FPGA芯片和嵌入式FPGA(eFPGA)硅知识产权(IP)领域的领先企业Achronix半导体公司,以及RISC-V工具和IP领域的行业领导者Blues…