なんかかきたい

プログラミングなどの個人的なメモやサークル「ゆきいろパラソル」の情報を載せてます

Elasticsearch 1.7から2.3にアップグレードする

重い腰を上げてElasticsearchのメジャーバージョンアップを行うことになったのでメモ。

引き続いてDebianを使っているのでDebian向けの内容になってます。

基本的なところ

メジャーバージョンアップになるけど、旧バージョンのインデックスを失うことはない。 注意点としてはクラスタの全ノードを停止する必要があるので、無停止でのアップグレードができない。

アップグレードガイド

後方互換を崩す変更 (2.3)

よく読んでおく。

elasticsearch.yml の設定を見直す。 バージョンアップ時に後方互換を失っている変更がいくつかあるので注意する。

oracle-java8-jdkのパッケージを作ってインストールして切り替える (オプション)

Elasticsearchの推奨Javaoracle-java8-jdkなので、Oracleのtar.gzからdebパッケージを作ってインストールする。

書いてる時点では 8u92 が用意されているので、 contrib から java-package をインストールしたら、

make-jpkg jdk-8u92-linux-x64.tar.gz
sudo dpkg -i oracle-java8-jdk_8u92_amd64.deb

とする。その後、 update-alternatives コマンドで使用するJavaのバージョンを変更する。

update-alternatives --config java

環境変数の設定

UbuntuなどDebian系のOSでパッケージからインストールしている場合、 /etc/default/elasticsearch環境変数を設定する。

ES1.xと同じように mlockall: true を設定する場合、ES_HEAP_SIZE は大きく設定しておく方がよい。 Java8を使う場合は、JVMのオプションも設定しておくのがいいかもしれない。

# ES_JAVA_OPTS="-server -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M"

swapの設定

swapすると遅いのでswapを無効にするか、swapしづらい設定にしておく。

Linuxでswapを無効にするには swapoff -a とする。

あるいはswapされにくいように vm.swappiness を 0 または 1 にする。

(Kernel 3.5 以上を使っている場合は、swappiness: 0 が無効なので 1 を設定する)

/etc/sysctl.conf

vm.swappiness = 0
# or
vm.swappiness = 1
sysctl -p

Shardの再配置を無効にしてディスクに同期しておく

ノードを全て落とす必要があるのでダウン時に再配置が行われないように事前に止めておく。

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

停止前の確認

あとは停止すればいいけど、healthやnodesのAPIで状態を確認しておくとよい。

curl -XGET http://localhost:9200/_cat/health
curl -XGET http://localhost:9200/_cat/nodes

elasticsearch-head pluginを使うと視覚的に見えて便利だけど、 ElasticsearchのバージョンによってAPIが変わってしまっているので使いこなすのがちょっと難しいかもしれない。 (1.x用のes-headを用意しておいてもバージョンアップ後接続エラーになってしまう) なので、curlでヘルスチェックするほうがお手軽だと思う。

Elasticsearchを止める

Debianを使っているなら init.d とか service コマンドなりで停止する。

sudo /etc/init.d/elasticsearch stop

新しいElasticsearchを入れる

Elasticsearchは2.xになってリポジトリのパスが変わっている。 古いリポジトリが残っている場合は先に消しておくと良い。

sudo rm /etc/apt/sources.list.d/elasticsearch-1.7.list
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
sudo aptitude update
sudo aptitude install elasticsearch

/etc/elasticsearch/elasticsearch.yml など debパッケージ管理下のファイルを変更しているとパッケージに含まれる新規のものを使うか、古いものを使うかを選ばなければならなくなる。 頑張ってMergeする感じになるけど、設定しないといけない項目はそれほど多くはないので、パッケージインストールされた設定を元に作り直してもいいと思う。

elasticsearch.yml

cluster.name: my-application
# HOSTNAMEをそのままつけると便利
node.name: ${HOSTNAME}

# Defaultでは master / data ともに true
# 違う設定にしたい場合は以下を変更
node.master: true
node.data: true

# Production設定
# 詳細は https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-node.html#max-local-storage-nodes
node.max_local_storage_nodes: 1

# データが格納されるディレクトリは以下で変更できる
# path.data: 

# セキュリティのためsnapshotディレクトリは事前に設定に記述しなければならなくなった
path.repo: /tmp/elasticsearch_snapshots

# bindするアドレス
network.host: 0.0.0.0

# multicast discoveryはデフォルトでは使えなくなった
discovery.zen.ping.unicast.hosts: ["192.168.0.1", "192.168.0.2"]

# (total number of nodes / 2 + 1)
discovery.zen.minimum_master_nodes: 2

index.number_of_shards: 5
index.number_of_replicas: 1
# 後述
index.max_result_window: 100000

# セキュリティのためデフォルトでgroovy dynamic scriptは使用できなくなった (1.4.3)
# script.engine.groovy.inline.search: true

プラグインを入れる

だいたいanalyzerにはkuromojiを使っていると思うので、一旦古いプラグインを消して再インストールする。

kuromoji は elastic リポジトリに移動されたので名前が変わっている。あと、サブコマンドの - はなくなって単に removeinstall とすればよくなった。

sudo /usr/share/elasticsearch/bin/plugin remove analysis-kuromoji
sudo /usr/share/elasticsearch/bin/plugin install analysis-kuromoji

Elasticsearchを起動してShardの再配置を有効にする

エラーなく起動が終わったらShardの再配置を有効にする。 (エラーがないかどうかは /var/log/elasticsearch/*.log を確認すればよい。)

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

ノードの状態を確認

curl -XGET http://localhost:9200/_cat/health
curl -XGET http://localhost:9200/_cat/nodes

問題がなければこの作業を繰り返してすべてのノードをアップグレードしていく。

余談

number_of_replicasの数がおかしくなってステータスがGreenにならない

number_of_replicas の数は動的に変更できるのでAPIを使って変更する。

curl -XPUT 'localhost:9200/foo_bar_index/_settings' -d '
{
    "index" : {
        "number_of_replicas" : 1
    }
}'

Result window is too large が出るようになった

Result window is too large, from + size must be less than or equal to: [10000] but was [10010]

このようなメッセージが出ることもある。 これはElasticsearch 2.1 より (from + size) にデフォルトで10000の制限がつくようになったため。 新規に作られるインデックスの制限値は elasticsearch.yml で変更できる。

elasticsearch.yml

index.max_result_window: 50000

既に作られているインデックスの値はAPIで変更できる。

curl -XPUT 'localhost:9200/foo_bar_index/_settings' -d ' { "index" : { "max_result_window" : 50000 } }'

今後とか

ElasticsearchのバージョンはKibanaと合わせて5になるらしい。 ついでにLuceneと合わせて6になると色々混乱がなくなって便利かなって気持ちがあるので、Solrみたいに6にならないかなとぼんやり。

あとはいい感じに動いていい感じに運用できるといいな。いい感じに。

追記

そういえばバージョンをあげたらMuninのPluginが動かなくなって悲しかったので新しく作りました。

Elasticsearch2用のmunin pluginです。

github.com

https://github.com/t-cyrill/munin-elasticsearch2

いい感じだと思ったら使ってみてください。