Elasticsearchの起動プロセスを追う

背景

もっとElasticsearchを理解できるように、基本から復習していきます。

(いつまで続くわからないけど)Elasticsearchを基礎から理解するシリーズ第3回はElasticsearchを起動プロセスを追ってみるです。

前回はlocalビルドして、JVMのオプションの設定をして起動コマンドのところまでを見ました。

今回は前回の続きで起動コマンドのエントリポイントから、Nodeが起動されるまでのプロセスを追ってみたいと思います。

免責

Elasticsearchについて調べたことをまとめています。また、JAVAは初心者です。

おそらく間違えていることがあると思うので、間違いに気づいたらご連絡いただけると嬉しいです。

特に今回の部分は筆者の知識不足からなにをしているかわからないところが多かったため、間違っている可能性がとても高いです。

環境

前回の復習

Elasticsearchの起動はスクリプトを見る限り、org.elasticsearch.bootstrap.Elasticsearchがエントリーポイントのようでした。

exec \  
  "$JAVA" \  
  "$XSHARE" \  
  $ES_JAVA_OPTS \  
  -Des.path.home="$ES_HOME" \  
  -Des.path.conf="$ES_PATH_CONF" \  
  -Des.distribution.flavor="$ES_DISTRIBUTION_FLAVOR" \  
  -Des.distribution.type="$ES_DISTRIBUTION_TYPE" \  
  -Des.bundled_jdk="$ES_BUNDLED_JDK" \  
  -cp "$ES_CLASSPATH" \  
  org.elasticsearch.bootstrap.Elasticsearch \  
  "$@" <<<"$KEYSTORE_PASSWORD"

org.elasticsearch.bootstrap.Elasticsearch でやっていること

main

以下がorg.elasticsearch.bootstrap.Elasticsearchのmainメソッドです。

public static void main(final String[] args) {  
  
    Bootstrap bootstrap = initPhase1();  
    assert bootstrap != null;  
  
    try {  
        initPhase2(bootstrap);  
        initPhase3(bootstrap);  
    } catch (NodeValidationException e) {  
        bootstrap.exitWithUserException(ExitCodes.CONFIG, e);  
    } catch (Throwable t) {  
        bootstrap.exitWithUnknownException(t);  
    }  
}

elasticsearch/Elasticsearch.java at main · elastic/elasticsearch · GitHub

初期化プロセスが3つのフェーズに分かれています。

先にまとめると各フェーズはざっくり以下の役割です。

  • Phase1
    • CLIのコマンドや設定ファイルの読み込み、各種初期化
  • Phase2
    • セキュリティマネージャーの初期化やマシンの物理サイズやCPU情報などの取得
  • Phase3
    • Nodeの起動

Phase1

phase1では諸々の初期化が行われます。

https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java#L93-L137

コメントでは、「いくつかの静的な初期化、CLIプロセスからの引数の読み込み、ログの初期化」となっていますが、実装を追っていくと具体的には以下のことが行われています。

  • SecurityPropertyの初期化
    • DNSキャッシュ(networkaddress.cache.ttlnetworkaddress.cache.negative.ttl)が指定されていた場合に上書きする。
  • セキュリティマネージャーの初期化
    • JavaSecurityManagerを作成する
      • 内部ポリシーの決定をセキュリティマネージャーが存在するように動作あるように動作させたいので、JVMにセキュリティマネージャーがインストールされているように思わせる。らしいがまったく意味がわからなかった。。。
    • あとで必要なポリシーを設定できるようにすべての権限を付与しています。
  • bootstrapの初期化
  • Nodeの設定ファイルのパスを取得
    • configディレクトリにあるelasticsearch.ymlのパスを取得します。
    • Environmentクラスのインスタンス作成時にコンストラクタにパスを渡しています。コメントにある通りここではパス(=文字列)を使っているだけのようです。
  • Bootstrapのインスタンスを生成する

※JSMについて、およびすべての権限を付与する理由は次のブログ参照

blog.cybozu.io

Phase2

phase2ではセキュリティに関する初期化が行われます。

ここは色々わからなすぎました...

https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java#L139-L191

コメントには「セキュリティマネージャーの初期化までと、それ以降のすべての作業」とあります。 それ以降のすべての作業とは???

Phase3

Phase3ではNodeを起動します。 https://github.com/elastic/elasticsearch/blob/main/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java#L194-L245

Nodeの実装はまた別の機会に....

感想

Elasticsearchの起動プロセスを見てきましたが、起動だけでこんなに多くのプロセスがあるのか...ということが理解できました。 「あのプロパティはここで使われているのか〜」という発見もありました。

ただし、きちんと理解するにはLinuxJVMの知識がもっと必要そうです。 また改めて挑戦したいと思いつつ、起動からおっていくものじゃないなと思いました...