最近Elasticsearchを触っていて、まずはローカル開発環境を作ることになった。ただ、Elasticsearchはバージョンがかなり変わり、別プロジェクトと利用したいバージョンが異なっていたので、プロジェクト単位で使い分けるにはどうすればよいかを考えた。
やりたいこと
作戦
セットアップスクリプトを作る
セットアップスクリプトに求める機能要件は以下のとおり。
- 指定したバージョンのElasticsearchが自動でダウンロードされ、elasticsearch/ディレクトリ以下に展開される
- 必要なプラグインが自動でインストールされる
- バージョン情報を変えると、自動でそのバージョンに変更してくれる
また、このセットアップスクリプトの非機能要件としては以下のとおり。
- 何度実行しても同じ状態になる(冪等である)
- 必要ないのにデータのダウンロードをしない(高速である)
冪等であれば、何かあったらもう一回セットアップスクリプトを実行してくれたら直るとか、プラグインを追加した時も何も考えずセットアップスクリプトを実行してくださいということができ、利用が簡単である。また高速であれば、例えば他の開発者に簡単に利用できるようにローカルサーバ起動時に自動でセットアップスクリプトを呼ぶなどをしても、特にストレス無く開発できる。
このような要件を満たすセットアップスクリプトをPerlで作成した。特にPerlである必要はなく、適当に好きな言語を使ってもらっても作れるはず。
setup-local-elasticsearch.pl
#!/usr/bin/env perl use strict; use warnings; use utf8; use feature qw(say); # バージョン情報 my $ELASTICSEARCH_VERSION = '2.3.4'; # tarをdownloadして、elasticsearch/以下に配置するコマンド # 指定したバージョンのダウンロードリンクからダウンロードし、elasticsearch/ディレクトリ以下に展開する my $get_elasticsearch_command = <<"COMMAND"; curl -O https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/tar/elasticsearch/$ELASTICSEARCH_VERSION/elasticsearch-$ELASTICSEARCH_VERSION.tar.gz 2>/dev/null; tar zxf elasticsearch-$ELASTICSEARCH_VERSION.tar.gz; mv elasticsearch-$ELASTICSEARCH_VERSION elasticsearch; rm -f elasticsearch-$ELASTICSEARCH_VERSION.tar.gz COMMAND # ---- ElasticSearchをインストールする ---- if (-e "elasticsearch/") { # elasticsearch/ディレクトリがあれば、バージョンの変化がないかチェックし、 # 変化があれば更新する my ($version) = `elasticsearch/bin/elasticsearch --version` =~ /\AVersion: ([0-9.]+)/; unless ($version eq $ELASTICSEARCH_VERSION) { say "update elasticsearch..."; system "rm -rf elasticsearch"; system $get_elasticsearch_command; say "elasticsearch update was done"; } } else { # そもそもelasticsearch/ディレクトリがなければ新規でセットアップ say "Download and install elasticsearch..."; system $get_elasticsearch_command; say "elasticsearch setup was done"; } # ---- Javaのバージョンの確認を行う ---- # https://www.elastic.co/guide/en/elasticsearch/hadoop/current/requirements.html#requirements-jdk # によると、JDK 8以上が強く推奨されているのでチェックを行っておく my ($java_version) = `java -version 2>&1` =~ /java version "(\d+\.\d+)/; unless ($java_version >= 1.8) { say ''; say "!!!!!!!! NOTICE !!!!!!!!"; say "Elasticsearch requires recent java."; say "Please download and install recent java from the following URL."; say "http://www.oracle.com/technetwork/java/javase/downloads/index.html"; exit 1; } # ---- 必要なpluginのインストールを行う ---- # すでにインストールされているプラグインをリストアップ my $is_installed = do { my $output = `elasticsearch/bin/plugin list`; my @list = $output =~ /^ - (.+)$/mg; +{ map { $_ => 1 } @list }; }; # plugin listで表示される名前と、インストールに利用する名前は違うため # [ (plugin名), (installに渡す名前) ] の組を書いておく my $plugins = [ [ 'head' , 'mobz/elasticsearch-head' ], [ 'elasticsearch-inquisitor' , 'polyfractal/elasticsearch-inquisitor' ], [ 'analysis-kuromoji' , 'analysis-kuromoji' ], [ 'analysis-icu' , 'analysis-icu' ], ]; for my $plugin (@$plugins) { my ($name, $install_name) = @$plugin; # すでにインストールされているなら省略 next if $is_installed->{$name}; say "Install $name plugin..."; system "./elasticsearch/bin/plugin install --batch $install_name >/dev/null 2>&1"; }
このスクリプトを実行しさえすればElasticsearchのセットアップやプラグインのインストールを自動で行うことができる。またすでにセットアップが終わっていればElasticsearchのダウンロードやプラグインのインストールをしないので、二回目以降は高速に実行が出来る。もしバージョンを変えたくなった場合も、スクリプトの最初の方にある$ELASTICSEARCH_VERSION変数を変更して、セットアップスクリプトを実行し直すだけですぐに変更できる。
あとはこれをプロジェクト全体のセットアップスクリプトに組み込んだり、初期セットアップフローにこれを実行するようにしてもらえば、チームメンバーも簡単にセットアップできるようになる。自分のプロジェクトではプロジェクト全体のセットアップスクリプトがあり、それがローカルサーバ起動時に呼ばれるようになっているので、そちらに組み込んでいる。
セットアップしたElasticsearchは以下のように起動すれば良い。クラスタ名も明示的に付け、他のプロジェクトと誤ってクラスタリングされないようにしておく。
$ elasticsearch/bin/elasticsearch --cluster.name=myproject