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

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文主要解决以下问题: 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可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
6月前
|
自然语言处理 API 索引
Elasticsearch Analyzer原理分析并实现中文分词
Elasticsearch Analyzer原理分析并实现中文分词
108 0
|
6月前
|
搜索推荐 Java 数据处理
Elasticsearch搜索分析引擎本地部署与远程访问
Elasticsearch搜索分析引擎本地部署与远程访问
|
18天前
|
存储 SQL 监控
|
18天前
|
运维 监控 安全
|
2月前
|
存储 缓存 自然语言处理
深度解析ElasticSearch:构建高效搜索与分析的基石
【9月更文挑战第8天】在数据爆炸的时代,如何快速、准确地从海量数据中检索出有价值的信息成为了企业面临的重要挑战。ElasticSearch,作为一款基于Lucene的开源分布式搜索和分析引擎,凭借其强大的实时搜索、分析和扩展能力,成为了众多企业的首选。本文将深入解析ElasticSearch的核心原理、架构设计及优化实践,帮助读者全面理解这一强大的工具。
195 7
|
6月前
|
JSON 监控 Java
Elasticsearch 8.X reindex 源码剖析及提速指南
Elasticsearch 8.X reindex 源码剖析及提速指南
94 0
|
3月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码【完结篇】
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码【完结篇】
61 0
|
4月前
|
运维 监控 Java
在大数据场景下,Elasticsearch作为分布式搜索与分析引擎,因其扩展性和易用性成为全文检索首选。
【7月更文挑战第1天】在大数据场景下,Elasticsearch作为分布式搜索与分析引擎,因其扩展性和易用性成为全文检索首选。本文讲解如何在Java中集成Elasticsearch,包括安装配置、使用RestHighLevelClient连接、创建索引和文档操作,以及全文检索查询。此外,还涉及高级查询、性能优化和故障排查,帮助开发者高效处理非结构化数据。
72 0
|
6月前
|
存储 JSON API
【Elasticsearch专栏 16】深入探索:Elasticsearch的Master选举机制及其影响因素分析
Elasticsearch,开源搜索和分析引擎,以其分布式特性受开发者喜爱。本文聚焦其Master选举过程,关键在于保障集群稳健和高可用。Master负责集群操作,数据节点存储数据。选举在Master不可用时发生,基于Zen Discovery模块,遵循多数派协议。选举过程包括启动发现、选举触发、节点投票和状态同步。相关命令和配置有助于管理选举和集群状态。理解和优化选举机制能提升Elasticsearch集群的性能和稳定性。
117 1
|
6月前
|
存储 Serverless 定位技术
深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析
深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析
157 0
下一篇
无影云桌面