Elasticsearchのバージョンアップ

ElasticSearchがいつの間にやらメジャーバージョンアップしているので、僕の環境のもバージョンアップしてみます。(2から5にバージョンアップしていますが、3と4はどこへ。。。)

(→ 2017/04/10追記:コメントで教えてくれた方がいました!!Kibanaとバージョンを揃える意味で、バージョン5に飛んだみたいです。)

以下が環境です。

  • CentOS7.2
  • ElasticSearch 2.4.1 → 5.2.1

公式の手順を参考にすすめていきます。

Upgrading Elasticsearch | Elasticsearch Reference [5.2] | Elastic

ただバージョンアップもそこそこめんどいので、スナップショットであれば異なるバージョン間でも移行できるみたいですから、完全新規でElasticsearchを作成して、スナップショットを利用してインデックスを移し替えるのもありだと思いました。

Snapshot And Restore | Elasticsearch Reference [5.2] | Elastic

バックアップ

バージョンアップ前にバックアップを取得しておけと指示されています。ElasticSearchのインデックス・バックアップ方法に関しては、以前の投稿を参考にしてください。

Elasticsearchのバックアップ - goodbyegangsterのブログ

バージョンアップ前のチェック

「Elasticsearch Migration Helper」というバージョンアップ前のチェックツールが、pluginとして提供されています。これを利用してみます。

GitHub - elastic/elasticsearch-migration: This plugin will help you to check whether you can upgrade directly to the next major version of Elasticsearch, or whether you need to make changes to your data and cluster before doing so.

$ cd /usr/share/elasticsearch
$ sudo ./bin/plugin install https://github.com/elastic/elasticsearch-migration/releases/download/v2.0.4/elasticsearch-migration-2.0.4.zip

以下のURLで画面にアクセスできます。

http://(サーバー名)/_plugin/elasticsearch-migration/

尚、リモートクラスタを対象とする場合、ElasticSearch側でCORS(Cross-Origin Resource Sharing)の設定を有効にしておく必要があります。僕の環境は単一ノード構成なので、この点は試していません。詳しくは公式ドキュメントを参照してください。

実際にチェックを実施してみた結果。

f:id:goodbyegangster:20170315201237p:plain

僕の環境では幾つかのpluginがバージョン対応していないことと、ファイルディスクリプタの上限値が低すぎるようです。ちなみにElasticsearchをバージョンアップしても、既存で導入しているpluginのバージョンはそのままなので、導入済みpluginの対応状況については、事前に調べておけと公式でも言ってますね。

ファイルディスクリプタについては、パラメータファイル「/usr/lib/systemd/system/elasticsearch.service」内の該当箇所を更新。

# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536

導入しているpluginに関して、「elasticsearch-head」はバージョン5からはpluginとしてではなく、独立したWEBサーバとして起動するようです。9100番のポートを利用するようです。

GitHub - mobz/elasticsearch-head: A web front end for an elastic search cluster

「elasticsearch-HQ」については、現在対応作業中みたいで、まだVer5では使えないようです。

GitHub - royrusso/elasticsearch-HQ: Monitoring and Management Web Application for ElasticSearch instances and clusters.

なので、上記2つのpluginについては、バージョンアップ前にアンインストールしてしまいます。

$ sudo /usr/share/elasticsearch/bin/plugin remove head
-> Removing head...
Removed head
$ sudo /usr/share/elasticsearch/bin/plugin remove hq
-> Removing hq...
Removed hq

サービスを再起動して、もう1度チェックしたらオールグリーンになっていました。

バージョンアップ

バージョンアップの手順ですが、僕の環境では「Full Cluster restart」という方法になります。尚、バージョンアップ時にはElasticsearchのサービスを停止する必要があるので、インデクシングが発生しないよう手筈を取っておくべきです。どこまでデータを取り込んだか分からなくなり、取り込み漏れが発生する恐れがあります。

公式はこちら。

Full cluster restart upgrade | Elasticsearch Reference [5.2] | Elastic

(1) shard allocation の停止

ノード停止時にレプリケーションが走ってしまわないよう、shard allocationを停止しておきます。

$ curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{
  "persistent": {
    "cluster.routing.allocation.enable": "none"
  }
}'

確認。

$ curl -XGET 'http://localhost:9200/_cluster/settings?pretty'
{
  "persistent" : {
    "cluster" : {
      "routing" : {
        "allocation" : {
          "enable" : "none"
        }
      }
    }
  },
  "transient" : { }
}

(2) synced flush の手動実行

synced flushとは、Elasticsearchでのサービス起動高速化の仕組み、らしいです。Elasticsearchでは、過去5分間インデクシング処理が何も実行されていない場合、synced flushという処理が実行され、全てのshardに対してsync_idという同一の値が与えられます。この同一の値がreplicaも含めた全てのshardにあることにより、次にElasticsearchのサービスを起動した際、各shard上のデータの整合性が担保される事となり、起動時の不要なチェック処理やコピー処理が走らないようなるらしく、通常より早く起動できるますねって話とのことです。

このsynced flushを手動で、明示的に実行します。コマンドは以下。

$ curl -XPOST 'http://localhost:9200/_flush/synced?pretty'

(3) ノードを停止してアップグレード

全ノードを停止させて、RPMパッケージをインストールします。

$ sudo systemctl stop elasticsearch.service

ver5用のリポジトリを作成してあげて、新しいバージョンをインストールします。

$ sudo vi /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-5.x]
name=Elasticsearch repository for 5.x packages
baseurl=https://artifacts.elastic.co/packages/5.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

$ sudo yum install elasticsearch

僕の環境では、インストール中に以下のメッセージが表示されました。幾つかのファイルが、上書きされることなく「rpmnew」拡張子付きで配布されています。

warning: /etc/elasticsearch/elasticsearch.yml created as /etc/elasticsearch/elasticsearch.yml.rpmnew
warning: /etc/sysconfig/elasticsearch created as /etc/sysconfig/elasticsearch.rpmnew
warning: /usr/lib/systemd/system/elasticsearch.service created as /usr/lib/systemd/system/elasticsearch.service.rpmnew

この点気づかずにサービスを起動しようとすると、以下のように無効なパラメータがあるよと怒られたり。

 3月 14 19:54:37 localhost.localdomain systemd[1]: Starting Elasticsearch...
 3月 14 19:54:37 localhost.localdomain systemd[1]: Started Elasticsearch.
 3月 14 19:54:37 localhost.localdomain polkitd[716]: Unregistered Authentication Agent for unix-process:10000:302214 (system bus name :1.85, object pa
 3月 14 19:54:37 localhost.localdomain elasticsearch[10010]: Error: encountered environment variables that are no longer supported
 3月 14 19:54:37 localhost.localdomain elasticsearch[10010]: Use jvm.options or ES_JAVA_OPTS to configure the JVM
 3月 14 19:54:37 localhost.localdomain elasticsearch[10010]: ES_HEAP_SIZE=1g: set -Xms1g and -Xmx1g in jvm.options or add "-Xms1g -Xmx1g" to ES_JAVA_OPTS
 3月 14 19:54:37 localhost.localdomain systemd[1]: elasticsearch.service: main process exited, code=exited, status=1/FAILURE
 3月 14 19:54:37 localhost.localdomain systemd[1]: Unit elasticsearch.service entered failed state.
 3月 14 19:54:37 localhost.localdomain systemd[1]: elasticsearch.service failed.

systemd内Elasticsearch起動スクリプトの差異から、そんなオプション知らねえからと怒られて、サービスが起動しないです。。。

Mar 15 02:19:34 localhost systemd: Starting Elasticsearch...
Mar 15 02:19:34 localhost systemd: Started Elasticsearch.
Mar 15 02:19:36 localhost elasticsearch: starts elasticsearch
Mar 15 02:19:36 localhost elasticsearch: Option                Description
Mar 15 02:19:36 localhost elasticsearch: ------                -----------
Mar 15 02:19:36 localhost elasticsearch: -E <KeyValuePair>     Configure a setting
Mar 15 02:19:36 localhost elasticsearch: -V, --version         Prints elasticsearch version information and exits
Mar 15 02:19:36 localhost elasticsearch: -d, --daemonize       Starts Elasticsearch in the background
Mar 15 02:19:36 localhost elasticsearch: -h, --help            show help
Mar 15 02:19:36 localhost elasticsearch: -p, --pidfile <Path>  Creates a pid file in the specified path on start
Mar 15 02:19:36 localhost elasticsearch: -q, --quiet           Turns off standard ouput/error streams logging in console
Mar 15 02:19:36 localhost elasticsearch: -s, --silent          show minimal output
Mar 15 02:19:36 localhost elasticsearch: -v, --verbose         show verbose output
Mar 15 02:19:36 localhost elasticsearch: ERROR: D is not a recognized option
Mar 15 02:19:36 localhost systemd: elasticsearch.service: main process exited, code=exited, status=64/n/a
Mar 15 02:19:36 localhost systemd: Unit elasticsearch.service entered failed state.
Mar 15 02:19:36 localhost systemd: elasticsearch.service failed.

(4) コンフィグファイルの修正

上記の点から、ファイルを更新しておく必要があります。「elasticsearch.yml」は現行そのまま利用して、「/etc/sysconfig/elasticsearc」と「/usr/lib/systemd/system/elasticsearch.service」は必要パラメータを転記した後、新旧で置き換えます。

JAVAのヒープサイズ

利用するjavaのヒープサイズについて、Ver2.4の時はES_HEAP_SIZEというパラメータを利用していましたが、jvm.optionsというパラメータに変更になっています。公式を見るといくつか変更する方法があるようですが、「/etc/sysconfig/elasticsearch」ファイルを更新する方法をとります。「elasticsearch.rpmnew」ファイルを更新して、前バージョンのファイルと置き換えてます。

$ sudo vi /etc/sysconfig/elasticsearch.rpmnew

# Additional Java OPTS
ES_JAVA_OPTS="-Xms1g -Xmx1g" ./bin/elasticsearch

JAVAヒープのパラメータ以外にも、変更していたパラメータがあった場合、新しいほうに転記しておきます。

$ mv /etc/sysconfig/elasticsearch.rpmnew /etc/sysconfig/elasticsearch

Set JVM heap size via jvm.options | Elasticsearch Reference [5.2] | Elastic

②メモリのスワップ無効化

続いて、メモリのスワップ無効化について。前バージョンと同じくmlockallを利用してスワップを防ぎます。「elasticsearch.yml」にmlockall有効化の設定を入れる必要があるのですが、「elasticsearch.yml」は前バージョンままのファイルを利用することとするので、パラメータ更新作業は不要です。

Disable swapping | Elasticsearch Reference [5.2] | Elastic

ただし、systemdでサービス管理されている場合、以下のファイルを追加してあげておかないと、mlockallの設定が有効にならないようです。

$ sudo mkdir /etc/systemd/system/elasticsearch.service.d
$ sudo vi /etc/systemd/system/elasticsearch.service.d/elasticsearch.conf
[Service]
LimitMEMLOCK=infinity

Configuring system settings | Elasticsearch Reference [5.2] | Elastic

③ファイルディスクリプタとnmapの上限値

rpmで入れた場合、ファイルディスクリプタは自動的に65536に、nmapは自動的に最適値に設定されるので、作業不要とのこと。

④利用可能スレッド(プロセス)数

最低でも2048は欲しいとのことです。ので、limits.confを編集。

$ sudo vi /etc/security/limits.conf
elasticsearch   hard    nproc           2048

Number of threads | Elasticsearch Reference [5.3] | Elastic

⑤Elasticsearch起動スクリプトファイルの更新

systemdでのElasticsearch起動スクリプトファイルである「elasticsearch.service」はrpmnewのものと置き換えてしまいます。でないと起動しないです。

$ sudo mv /usr/lib/systemd/system/elasticsearch.service.rpmnew /usr/lib/systemd/system/elasticsearch.service

(5) Elasticsearchの起動

ようやく起動できますよ。

$ sudo systemctl daemon-reload
$ sudo systemctl start elasticsearch.service

で、起動しないでやんの(笑)。。。。ログを見てみるとkuromojiが怒られてる。

$ sudo tail -n 100 /var/log/elasticsearch/elasticsearch.log
[2017-03-15T18:20:10,539][INFO ][o.e.n.Node               ] [] initializing ...
[2017-03-15T18:20:10,581][INFO ][o.e.e.NodeEnvironment    ] [6qrzY9f] using [1] data paths, mounts [[/ (rootfs)]], net usable_space [17.3gb], net total_space [26.3gb], spins? [unknown], types [rootfs]
[2017-03-15T18:20:10,581][INFO ][o.e.e.NodeEnvironment    ] [6qrzY9f] heap size [1007.3mb], compressed ordinary object pointers [true]
[2017-03-15T18:20:10,584][INFO ][o.e.n.Node               ] node name [6qrzY9f] derived from node ID [6qrzY9fCQJq2zngbPS92mg]; set [node.name] to override
[2017-03-15T18:20:10,585][INFO ][o.e.n.Node               ] version[5.2.2], pid[154818], build[f9d9b74/2017-02-24T17:26:45.835Z], OS[Linux/3.10.0-514.2.2.el7.x86_64/amd64], JVM[Oracle Corporation/OpenJDK 64-Bit Server VM/1.8.0_111/25.111-b15]
[2017-03-15T18:20:11,082][ERROR][o.e.b.Bootstrap          ] Exception
java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] is incompatible with Elasticsearch [5.2.2]. Was designed for version [2.4.1]
        at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:108) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.plugins.PluginsService.getPluginBundles(PluginsService.java:292) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:131) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.node.Node.<init>(Node.java:297) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.node.Node.<init>(Node.java:232) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap$6.<init>(Bootstrap.java:241) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:241) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:333) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:121) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:112) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.SettingCommand.execute(SettingCommand.java:54) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:122) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.Command.main(Command.java:88) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:89) [elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:82) [elasticsearch-5.2.2.jar:5.2.2]
[2017-03-15T18:20:11,084][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] is incompatible with Elasticsearch [5.2.2]. Was designed for version [2.4.1]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:125) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:112) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.SettingCommand.execute(SettingCommand.java:54) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:122) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.cli.Command.main(Command.java:88) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:89) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:82) ~[elasticsearch-5.2.2.jar:5.2.2]
Caused by: java.lang.IllegalArgumentException: Plugin [analysis-kuromoji] is incompatible with Elasticsearch [5.2.2]. Was designed for version [2.4.1]
        at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:108) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.plugins.PluginsService.getPluginBundles(PluginsService.java:292) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:131) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.node.Node.<init>(Node.java:297) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.node.Node.<init>(Node.java:232) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap$6.<init>(Bootstrap.java:241) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:241) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:333) ~[elasticsearch-5.2.2.jar:5.2.2]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:121) ~[elasticsearch-5.2.2.jar:5.2.2]
        ... 6 more

なので、kuromojiを一旦削除して、最新をインストールしておきます。合わせてマイグレーションチェックのやつも削除しておきます。ver5になったことで、pluginのコマンドが若干変わっています。

# sudo /usr/share/elasticsearch/bin/elasticsearch-plugin remove analysis-kuromoji
-> Removing analysis-kuromoji...
# sudo /usr/share/elasticsearch/bin/elasticsearch-plugin remove elasticsearch-migration
-> Removing elasticsearch-migration...
# sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install analysis-kuromoji
-> Downloading analysis-kuromoji from elastic
[=================================================] 100%??
-> Installed analysis-kuromoji

これで、ようやく起動できました。

$ sudo systemctl start elasticsearch.service

(6) shard allocation の再開

無効化したshard allocationを有効化しておきます。

$ curl -XPUT 'http://localhost:9200/_cluster/settings' -d '{
"persistent": {
    "cluster.routing.allocation.enable": "all"
  }
}'

確認

最後にhealthがgreenになっていることを確認します。

$ curl -XGET 'http://localhost:9200/_cat/health'
1489573598 19:26:38 elasticsearch green 1 1 0 0 0 0 0 0 - 100.0%

同時に検索もできることを確認しましょう。