Elasticsearch v2.3 から v5.6 にバージョンアップしました

永田です。

ようやく。

先日おこなった Elasticsearch のバージョンアップについて書きます。

ちょうど年末に Cookpad の中の方がとても良い記事を書いていらっしゃいます。

qiita.com

私も色々と参考にさせていただきました。

ただバージョンアップといっても、使っている機能によって気にするところが色々違います。 この記事も今からバージョンアップされる方の参考になればと思います。

はじめに

2系から5系って、メジャーバージョンが3つもあがってるやん、って思いますが実はそうではないです。 Elasticsearchが2系のときに、関連製品である(いわゆる Elastic Stack)Kibana や Logstash とバージョンを合わせるため、一気にすべてが5系に上がったと記憶しています。

そしてもう Elasticsearch は6系が出ています。

概要

大きく以下のステップを実施しました。

  • jdk のバージョンアップ
  • elasticsearch 5.6 バージョンアップ
  • elasticsearch-rails gem バージョンアップ
  • deprecated なコードを修正

jdkのバージョンアップ

elasticsearch 5系は java8 が必須です。 2系を使っていた頃は open-jdk7 を使っていたのですが、これを機に、oracle-jdk8 に変えました(もう世の中ではJava10と騒いでいますが) まずは 2系を oracle-jdk8 で動かすようにしました。

elasticsearch 5.6 バージョンアップ

移行プラグインで事前調査

まずは移行プラグインで、移行に際して修正すべき点をチェックします。 2系から5系への移行の場合は、 https://github.com/elastic/elasticsearch-migration/tree/2.x を、2系の plugin でインストールします。

./bin/plugin install https://github.com/elastic/elasticsearch-migration/releases/download/v2.0.4/elasticsearch-migration-2.0.4.zip

以下、そのプラグインで挙がった指摘事項です。

Site plugin are no longer supported

サイトプラグインというのは、画面を持つプラグインということでしょう。 2系では、head と inquisitor を使っていましたが、もうプラグインとしては使えなくなります。

ここではひとまず使えないということを理解しておいて、5系ではインストールしないようにするということに注意します。

At least 65536 file descriptors must be available to Elasticsearch

2系利用時は 65535 に設定していました・・・・。

/etc/security/limits.conf の 65535 を 65536 に変更しました。

                soft    nofile          65536
                hard    nofile          65536

bootstrap.mlockall is set to true but mlockall has failed (elasticsearch.yml)

もともとの mlockall をコメントアウトし、memory_lock を付け足して有効にしました

#bootstrap.mlockall: true
bootstrap.memory_lock: true

index.mapper.dynamic can no longer be set in the config file (elasticsearch.yml)

コメントアウトしました。

#index.mapper.dynamic: false

discovery.zen.ping.timeout has been renamed to discovery.zen.ping_timeout (elasticsearch.yml)

言われたとおりにリネーム。

#discovery.zen.ping.timeout: 5s
discovery.zen.ping_timeout: 5s

以上で、移行プラグインの指摘の修正はおわりです。

その他の設定ファイルについて

  • 2系では、使っていた logging.yml は不要になります。代わりに、log4j2.properties を使うことになります。このファイルはES5 に同梱されています。
  • 2系では、elasticsearch.in.sh というスクリプトを用意し、その中で JAVA_OPTS をいじっていましたがこれも不要です。JAVA_OPTSの変更系の設定は jvm.options というファイルでおこないます。これもES5に同梱されています。

起動オプション

  • -Des.default.path.data から -Edefault.path.data という指定の仕方に変わっています。

メインのアップグレード作業

メジャーバージョンの変更なので Rolling Upgrade はできません。 下記のリンクにしたがって、Full Cluster Restart Upgrade をしましょう。

www.elastic.co

我々のサービスでは、Elasticsearch への一切の更新をとめるために計画停止をおこないました。 既存の2系のElasticsearch をすべてシャットダウンし、1台ずつ5系に更新しました。

elasticsearch-rails gem バージョンアップ

-gem 'elasticsearch-rails', '~> 2.0.1'
-gem 'elasticsearch-model', '~> 2.0.1'
+gem 'elasticsearch-rails', '~> 5.0.2'
+gem 'elasticsearch-model', '~> 5.0.2'

deprecated なコードを修正

クエリの修正

missing query はES5からはサポートされなくなったとのこと。

https://www.bountysource.com/issues/47368001-elasticsearch-5-transporterror-400-parsing_exception-no-query-registered-for-missing

{ missing: { field: 'field_name' } }

としていたところを、

{ bool: { must_not: { exists: { field: 'field_name' } } } }

としました。

elasticsearch_deprecation.log

ES5 にすると自動的にこのログをはいてくれます。

Deprecated field [lowercase_expanded_terms] used, replaced by [Decision is now made by the analyzer]

2系では以下のURLにあるように lowercase_expanded_terms というオプションが使えましたが、使えなくなったので外しました。

www.elastic.co

おわりに

上述の Qiita の記事では平均レスポンスタイムが2倍も速くなったとありましたが、うちではちゃんと計測できてませんが、体感はそこまでの変化はありません。 うちのサービスでは通常の検索はそこそこ速いですが、データ量に依存して遅いこともあり、検索レスポンスについてはまだまだ課題を抱えています。

いつもの

エンジニア募集してます! Ruby もやりたいし、Elasticsearch も触ってみたい!ってひとは声かけてくださいねー。