Elasticsearchをlocalビルドで起動(その1)

背景

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

(いつまで続くわからないけど)Elasticsearchを基礎から理解するシリーズ第2回はElasticsearchを起動するです。

公式に提供されているDocker imageを使うことが推奨されていますが、今回はlocalにビルドして動かしてみます。

elasticsearch | Docker @ Elastic

免責

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

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

環境

事前準備

リポジトリ準備

github.com

執筆時(2022/11/28)の最新のmasterのコミットは 6871283です。

Gradleインストール

ElasticsearchのビルドシステムはGradleを使っているのでインストールする。 gradle.org

localでのビルド

リポジトリに移動して

cd 任意のパス/elastic/elasticsearch

次のコマンドを実行

./gradlew localDistro

build/ディレクトリができる。

ハマったポイント

最初なにも気にせずJAVA18を使っていたら Unsupported class file major version 62 というエラーがでたので、Amazon Corretto version 16.0.2をインストール。 ※inteliJでそれっぽいものをインストールしたので、とくにこだわりあるわけではないです。適宜JAVA16を使えるようにしてください。

再度 ./gradlew localDistro 実行。

起動

build/ディレクトリ配下にある起動スクリプトを実行します。

 cd build/distribution/local/elasticsearch-8.0.0-SNAPSHOT   
 ./bin/elasticsearch 

いつものようにログがいっぱい流れたので、起動に成功したようです。

一応確認します。

>>> curl -X GET http://localhost:9200/                                 

{"error":{"root_cause":[{"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}}],"type":"security_exception","reason":"missing authentication credentials for REST request [/]","header":{"WWW-Authenticate":"Basic realm=\"security\" charset=\"UTF-8\""}},"status":401}%

認証通ってなくてエラー返っているけど、今回は起動できればいいのでとりあえずOK。

起動ステップを追ってみる

先程実行した起動コマンドを見てみます。

起動スクリプトでは、Elasticsearchの起動前にJVMオプションを環境変数として生成して起動時に指定します。

JVMオプションの設定

JVMオプションは、デフォルトのJVMオプションが設定されますが、カスタムオプションファイル(jvm.options.d)を用意するか、ES_JAVA_OPTSで変数指定することでオーバーライドできます。

具体的に処理を見てみます。

ES_JAVA_OPTS=`export ES_TMPDIR; "$JAVA" "$XSHARE" -cp "$ES_CLASSPATH" org.elasticsearch.tools.launchers.JvmOptionsParser "$ES_PATH_CONF" "$ES_HOME/plugins"`

スクリプトはこのようになっています。 ES_PATH_CONF がカスタムオプションファイルなどの設定ファイルを指定するディレクトリです。

JvmOptionsParser を使ってパースされます。

JvmOptionsParserの中を見ていくと、

  1. システムのJVMOptionsが読み込まる。これを以降で上書きしていく。
  2. ES_JAVA_OPTSとカスタムオプションファイル のよみこみ&上書き
  3. 指定されたJVMオプションに基づいて、ElasticsearchのJVM設定の調整

が行われるようです。

起動スクリプトには以下のようなコメントがありますが、

# The JVM options parser produces the final JVM options to start Elasticsearch.  
# It does this by incorporating JVM options in the following way:  
#   - first, system JVM options are applied (these are hardcoded options in the  
#     parser)  
#   - second, JVM options are read from jvm.options and jvm.options.d/*.options  
#   - third, JVM options from ES_JAVA_OPTS are applied  
#   - fourth, ergonomic JVM options are applied

コードを見ると、 substitutedJvmOptionsが、まずjvmOptionsから作成された後に、カスタムオプションファイルの内容で上書きしているように見えます。

The ES_JAVA_OPTS variable overrides all other JVM options. We do not recommend using ES_JAVA_OPTS in production.

Advanced configuration | Elasticsearch Guide [8.6] | Elastic

ドキュメントにもこうある通り、ES_JAVA_OPTSの値が最後に上書きされるものだと思っていましたが、これはコードの理解が間違ってそうです... 理解が怪しいところですが、今後深追い&実際に動かして確認するとして今回は先に進みます。

いよいよ、ここからが起動の本番です。

スクリプトを見る限りエントリーポイントは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"

具体的にエントリポイントの中身を追っていきたいところですが、ここまででそこそこ長くなってきた&この先はもっと長いので、今回はここまで。 続きます。