Elasticsearch起動プロセスソースコード(一)

7410 ワード

Elasticsearch起動プロセスソースコード(一)
普段はesを使うことが多いので、esのソースコードを見て、esに対してもっとはっきりした認識を持って、まずesの起動過程から着手して、esが何をしたかを見て、起動に関連するクラスの初期化あるいはクラスの静的属性の初期化設定の具体的な機能は先に深く研究しないで、esのソースコードの読書の進展に従って一つ一つ説明することができると信じています.
主にBootstrapとinitialSettingsに関する

Esバージョン1.0
公式には/bin/elasticsearchを使用してesを起動することが示されています.まず/bin/elasticsearchというファイルを見てみましょう.
/bin/elasticsearch
if [ "x$daemonized" = "x" ]; then
    es_parms="$es_parms -Des.foreground=yes"
    exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS $es_parms -Des.path.home="$ES_HOME" -cp "$ES_CLASSPATH" $props \
            org.elasticsearch.bootstrap.Elasticsearch
    # exec without running it in the background, makes it replace this shell, we'll never get here...
    # no need to return something
else
    # Startup Elasticsearch, background it, and write the pid.
    exec "$JAVA" $JAVA_OPTS $ES_JAVA_OPTS $es_parms -Des.path.home="$ES_HOME" -cp "$ES_CLASSPATH" $props \
                org.elasticsearch.bootstrap.Elasticsearch 

以上のキーコードはjava実行のエントリがorg.elasticsearch.bootstrap.Elasticsearchであることを示しています.
org.elasticsearch.bootstrap.Elasticsearch.java

public class Elasticsearch extends Bootstrap {

    public static void close(String[] args) {
        Bootstrap.close(args);
    }

    public static void main(String[] args) {
        Bootstrap.main(args);
    }
}

実際にはBootstrapのmainメソッドが実行されています.このmainメソッドでは、initialSettings()メソッドが呼び出されます.
 private static Tuple initialSettings() {
        return InternalSettingsPreparer.prepareSettings(EMPTY_SETTINGS, true);
    }

まずEMPTYを見てみましょうSETTINGSって何?
org.elasticsearch.common.settings.ImmutableSettings.java

public class ImmutableSettings implements Settings {

    private ImmutableMap settings;
    private transient ClassLoader classLoader;

    ImmutableSettings(Map settings, ClassLoader classLoader) {
        this.settings = ImmutableMap.copyOf(settings);
        this.classLoader = classLoader;
    }

//     ,     get  

    public static class Builder implements Settings.Builder {
        public static final Settings EMPTY_SETTINGS = new Builder().build();

        private final Map map = new LinkedHashMap();

        private ClassLoader classLoader;

        private Builder() {

        }
        //     map clssLoader   
         public Settings build() {
            return new ImmutableSettings(Collections.unmodifiableMap(map), classLoader);
        }
    }   
}

静的内部クラスにより静的内部クラスBuilderによるmap(つまりプロファイル)の構築とClassLoaderの設定が実現され、外部クラスImmutableSettingsによりプロファイル情報が取得され、Builder().build()を呼び出す方法はCollections.unmodifiableMap(map)つまり外部クラスがプロファイルを変更できずsetメソッドとgetを分離することである.また、mapとclassloaderは、Builderオブジェクト上でのみ呼び出され、bulidメソッドを呼び出すと変更できないため、Immutablesettingsと呼ばれます.EMPTY_SETTINGSは、実際にはmapにkey,value,classLoaderが構成されていないImmutableSettingsを初期化しています.
public class InternalSettingsPreparer {

    public static Tuple prepareSettings(Settings pSettings, boolean loadConfigSettings) {
        boolean useSystemProperties = !pSettings.getAsBoolean("config.ignore_system_properties", false);
        ImmutableSettings.Builder settingsBuilder = settingsBuilder().put(pSettings);
        if (useSystemProperties) {
            //    , settingsBuilder       System.getProperties
        }
        Environment environment = new Environment(settingsBuilder.build());
        if (loadConfigSettings) {
            boolean loadFromEnv = true;
            if (useSystemProperties) {
                //    , settingsBuilder     ,   loadFromEnv
            }

            if (loadFromEnv){
                // settingsBuilder    resource(elasticsearch.yml,elasticsearch.json,elasticsearch.properties)     
            }
        }

        //    ,  node.name    clustername     settingsBuilder
         Settings v1 = settingsBuilder.build();
        environment = new Environment(v1);

        // put back the env settings
        settingsBuilder = settingsBuilder().put(v1);
        // we put back the path.logs so we can use it in the logging configuration file
        settingsBuilder.put("path.logs", cleanPath(environment.logsFile().getAbsolutePath()));

        v1 = settingsBuilder.build();

        return new Tuple(v1, environment);
    }
}

この関数の主な論理は、3つの構成に基づいてsettingとenvironmentを生成し、1.転送されたpSettings、すなわちprepareSettingsを呼び出すコードのbuilderのsetting 2.System.getPropertyのsetting 3.resourceプロファイルでは、Environmentが構築方法によってsettingsに転送されてインスタンス化され、environmentが何であるかを見ることができる.
public class Environment {

    private final Settings settings;

    private final File homeFile;

    private final File workFile;

    private final File workWithClusterFile;

    private final File[] dataFiles;

    private final File[] dataWithClusterFiles;

    private final File configFile;

    private final File pluginsFile;

    private final File logsFile;

    public Environment() {
        this(EMPTY_SETTINGS);
    }

    public Environment(Settings settings) {
        this.settings = settings;
        if (settings.get("path.home") != null) {
            homeFile = new File(cleanPath(settings.get("path.home")));
        } else {
            homeFile = new File(System.getProperty("user.dir"));
        }

        if (settings.get("path.conf") != null) {
            configFile = new File(cleanPath(settings.get("path.conf")));
        } else {
            configFile = new File(homeFile, "config");
        }

        if (settings.get("path.plugins") != null) {
            pluginsFile = new File(cleanPath(settings.get("path.plugins")));
        } else {
            pluginsFile = new File(homeFile, "plugins");
        }

        if (settings.get("path.work") != null) {
            workFile = new File(cleanPath(settings.get("path.work")));
        } else {
            workFile = new File(homeFile, "work");
        }
        workWithClusterFile = new File(workFile, ClusterName.clusterNameFromSettings(settings).value());

        String[] dataPaths = settings.getAsArray("path.data");
        if (dataPaths.length > 0) {
            dataFiles = new File[dataPaths.length];
            dataWithClusterFiles = new File[dataPaths.length];
            for (int i = 0; i < dataPaths.length; i++) {
                dataFiles[i] = new File(dataPaths[i]);
                dataWithClusterFiles[i] = new File(dataFiles[i], ClusterName.clusterNameFromSettings(settings).value());
            }
        } else {
            dataFiles = new File[]{new File(homeFile, "data")};
            dataWithClusterFiles = new File[]{new File(new File(homeFile, "data"), ClusterName.clusterNameFromSettings(settings).value())};
        }

        if (settings.get("path.logs") != null) {
            logsFile = new File(cleanPath(settings.get("path.logs")));
        } else {
            logsFile = new File(homeFile, "logs");
        }

    //    
}

Environmentはクラス名のように、実際にはsettings構成に基づいてファイルの初期化を行います.