【Elasticsearch 5.6.12 源码】——【2】启动过程分析(上)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 本文主要解决以下问题: 1、启动ES的入口类及入口方法是哪个? 2、分析梳理ES服务启动的主要流程?

版权声明:本文为博主原创,转载请注明出处!


简介

本文主要解决以下问题:

1、启动ES的入口类及入口方法是哪个?
2、分析梳理ES服务启动的主要流程?

入口类

ES的入口类为org.elasticsearch.bootstrap.Elasticsearch,启动方法为:

public static void main(final String[] args) throws Exception 

该类通过继承EnvironmentAwareCommand类增加了CLI的支持,类图:
image

启动流程

Step 1、给JVM安装(临时的)安全管理器,并注册错误日志监听器。

ES在程序启动的第一步先给JVM安装了一个安全管理器,并授予了程序所有的权限(临时的,后续会更换新的安全管理器),以方便以后的操作。接下来会注册一个错误日志的监听器,来监听是否有错误发生,随后使用配置文件配置日志组件是会检查监听器是否检测到错误,如果有将通过抛异常的方式中止ES的启动过程。执行该动作的方法:

    // org.elasticsearch.bootstrap.Elasticsearch
    public static void main(final String[] args) throws Exception 
Step 2、创建一个Elasticsearch类的实例(一个CLI的Command实例),并执行实例的main方法。

Elasticsearch类直接继承了EnvironmentAwareCommand,可以认为这一步创建了一个CLI的command对象。在该类的构造方法以及父类中定义了该command对象可以接受的cli的参数。执行该动作的方法:

// org.elasticsearch.bootstrap.Elasticsearch
public static void main(final String[] args) throws Exception 

bin目录下运行Elasticsearch -h命令,可以查看该实例支持的所有命令行参数:

image

Step 3、添加JVM关闭的构造,使用默认配置配置日志组件。

为JVM添加了一个shutdown的钩子函数,在钩子函数中调用了close()方法。使用系统属性es.logger.level的值来配置日志组件,如果没有该配置则使用默认的INFO级别来配置logger.level。执行该动作的方法:

// org.elasticsearch.cli.Command
public final int main(String[] args, Terminal terminal) throws Exception
Step 4、解析helpsilentverbosenormal的参数配置,并输出或设置到Terminal上。

首先检查控制台是否传入了-h--help参数,如果有的话打印帮助信息,并结束ES的启动过程。否则,依次检查-s-v等参数,并根据相应的参数配置terminal的信息输出方式。执行该动作的方法:

// org.elasticsearch.cli.Command
void mainWithoutErrorHandling(String[] args, Terminal terminal) throws Exception
Step 5、解析通过控制台传入的ES的配置参数,并根据配置参数创建Environment对象。

首先,解析通过控制台-E参数传入的ES配置。其次,通过System Property补齐某些确实的配置。这两个过程都会对配置的key进行查重。解析配置的代码:

// org.elasticsearch.cli.EnvironmentAwareCommand
protected void execute(Terminal terminal, OptionSet options) throws Exception {
        final Map<String, String> settings = new HashMap<>();
        for (final KeyValuePair kvp : settingOption.values(options)) {
            if (kvp.value.isEmpty()) {
                throw new UserException(ExitCodes.USAGE, "setting [" + kvp.key + "] must not be empty");
            }
            if (settings.containsKey(kvp.key)) {
                final String message = String.format(
                        Locale.ROOT,
                        "setting [%s] already set, saw [%s] and [%s]",
                        kvp.key,
                        settings.get(kvp.key),
                        kvp.value);
                throw new UserException(ExitCodes.USAGE, message);
            }
            settings.put(kvp.key, kvp.value);
        }

        putSystemPropertyIfSettingIsMissing(settings, "default.path.conf", "es.default.path.conf");
        putSystemPropertyIfSettingIsMissing(settings, "default.path.data", "es.default.path.data");
        putSystemPropertyIfSettingIsMissing(settings, "default.path.logs", "es.default.path.logs");
        putSystemPropertyIfSettingIsMissing(settings, "path.conf", "es.path.conf");
        putSystemPropertyIfSettingIsMissing(settings, "path.data", "es.path.data");
        putSystemPropertyIfSettingIsMissing(settings, "path.home", "es.path.home");
        putSystemPropertyIfSettingIsMissing(settings, "path.logs", "es.path.logs");

        execute(terminal, options, createEnv(terminal, settings));
    }

接下来,根据解析到的配置项来创建Environment对象。

// org.elasticsearch.cli.EnvironmentAwareCommand
protected Environment createEnv(Terminal terminal, Map<String, String> settings) {
    return InternalSettingsPreparer.prepareEnvironment(Settings.EMPTY, terminal, settings);
}

最终,通过InternalSettingsPreparer对象的prepareEnironment方法来创建Enironment对象。

// org.elasticsearch.node.InternalSettingsPreparer
public static Environment prepareEnvironment(Settings input, Terminal terminal, Map<String, String> properties)

该方法会合并控制台传入的配置项、部分通过系统环境变量设置的配置项及elasticsearch.yml设置的配置项。最终创建一个Environment对象,该对象中保存了ES程序的配置目录、数据目录、插件目录及日志目录的地址。

Step 6、解析控制台传入的-v-d-p-q等参数,并依据相应的参数初始化Bootstrap

首先,检查是否传入了-v参数,如果有该参数则打印ES的版本信息并退出。接下来解析-d-p-q参数,并依据这些参数调用Bootstrap.init。执行该动作的方法:

// org.elasticsearch.bootstrap.Elasticsearch
protected void execute(Terminal terminal, OptionSet options, Environment env) throws UserException
void init(final boolean daemonize, final Path pidFile, final boolean quiet, Environment initialEnv)
Step 7、通过调用BootstrapInfo.init()方法的方式来初始化BootstrapInfo对象。

通过这个对象可以获取JNA是否可用、系统Memory Lock是否可用等一些系统信息。执行该动作的方法:

// org.elasticsearch.bootstrap.Bootstrap
static void init(final boolean foreground, final Path pidFile,
            final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException
Step 8、创建一个Bootstrap实例,加载Secure Settings,并结合原有的配置重新创建Environment对象。

Bootstrap实例中首先启动了一个keep alive线程。结合SecureSettings重新创建Environment对象。依据env中的配置文件配置日志组件,这时会检查是否有错误日志产生。接下来输出一些配置相关的日志,并按需创建pidFile。执行该动作的方法:

// org.elasticsearch.bootstrap.Bootstrap
static void init(final boolean foreground, final Path pidFile,
            final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException
Step 9、检查Lucene的版本,设置 默认的未捕获异常的处理器 ,并开始配置新建的Bootstrap实例。

首先,根据是否守护经常运行的方式按需关闭SysOut。接下来检查Lucene库的版本是否匹配。最后,设置 DefaultUncaughtExceptionHandler。执行该动作的方法:

// org.elasticsearch.bootstrap.Bootstrap
static void init(final boolean foreground, final Path pidFile,
            final boolean quiet, final Environment initialEnv) throws BootstrapException, NodeValidationException, UserException
Step 10、设置NativePluginControllers,初始化native资源,初始化资源“探针”,checkJarHell,再次设置系统安全管理器并新建Node对象。

在这些过程中间还会检查老配置项bootstrap.seccomp和新配置项bootstrap.system_call_filter都配置了的情况下是否产生了冲突。执行该动作的方法:

// org.elasticsearch.bootstrap.Bootstrap
private void setup(boolean addShutdownHook, Environment environment) throws BootstrapException
Step 11、关闭SecureSettings的存储文件,并调用Bootstrap对象的start方法,按需closeSysError

这是启动流程的最后一步。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
30天前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
76 0
|
30天前
|
搜索推荐 Java 数据处理
Elasticsearch搜索分析引擎本地部署与远程访问
Elasticsearch搜索分析引擎本地部署与远程访问
|
30天前
|
JSON 监控 Java
Elasticsearch 8.X reindex 源码剖析及提速指南
Elasticsearch 8.X reindex 源码剖析及提速指南
34 0
|
30天前
|
存储 Serverless 定位技术
深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析
深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析
14 0
|
30天前
|
Kubernetes Java 索引
Elasticsearch 源码探究 001——故障探测和恢复机制
Elasticsearch 源码探究 001——故障探测和恢复机制
20 0
|
30天前
|
存储 JSON API
【Elasticsearch专栏 16】深入探索:Elasticsearch的Master选举机制及其影响因素分析
Elasticsearch,开源搜索和分析引擎,以其分布式特性受开发者喜爱。本文聚焦其Master选举过程,关键在于保障集群稳健和高可用。Master负责集群操作,数据节点存储数据。选举在Master不可用时发生,基于Zen Discovery模块,遵循多数派协议。选举过程包括启动发现、选举触发、节点投票和状态同步。相关命令和配置有助于管理选举和集群状态。理解和优化选举机制能提升Elasticsearch集群的性能和稳定性。
24 1
|
30天前
|
前端开发 Java iOS开发
elasticsearch8.1源码编译笔记
elasticsearch8.1源码编译笔记
65 0
|
30天前
|
Java iOS开发 MacOS
Elasticsearch7.4源码编译记录
Elasticsearch7.4源码编译记录
24 0
|
30天前
|
Java iOS开发 MacOS
Elasticsearch 6.5源码编译最新版
Elasticsearch 6.5源码编译最新版
24 0
Elasticsearch 6.5源码编译最新版
|
30天前
|
NoSQL Java API
SpringBoot【ElasticSearch集成 02】Java HTTP Rest client for ElasticSearch Jest 客户端集成(依赖+配置+增删改查测试源码)推荐使用
SpringBoot【ElasticSearch集成 02】Java HTTP Rest client for ElasticSearch Jest 客户端集成(依赖+配置+增删改查测试源码)推荐使用
68 0