Elasticsearch運用とか (4)
今回はelasticsearchのバージョンアップ手順をまとめます。 elasticsearch 1.0以降を使っている場合、ダウンタイムなしでアップグレードできます。
NOTE: 1.6以降の追記をしました (2015/10/22)
elasticsearchのゼロダウンタイムアップグレード
upgrading
elasticsearch 1.x 以上のバージョンを使っている場合、ダウンタイムなしでアップグレードすることができる。 ただし、後方互換性が含まれる場合があるので気をつけないといけない。 それぞれのバージョンでどのような変更がされているかはリリースノートのページにまとめられている。
elasticsearch 1.2
elasticsearch 1.3
1.3.0 から 1.3.1のようなマイナーバージョンチェンジの場合には後方互換性を崩さないみたい。
データのバックアップ
インデックスの消失が起こったときにも素早く復旧できるよう、データのバックアップを必ず取っておきたい。 elasticsearch 1.0以降のバージョンを使っているならスナップショットAPIを使って簡単にスナップショットを取れる。
とりあえずざっくりやるならファイルシステムに作ってもいいと思うので、ファイルシステムにスナップショットを作る手順をまとめます。
スナップショットのためのディレクトリを作る
sudo -u elasticsearch mkdir /tmp/elasticsearch_snapshots
スナップショットのリポジトリを作る
curl -XPUT 'http://localhost:9200/_snapshot/foo' -d '{ "type": "fs", "settings": { "location": "/tmp/elasticsearch_snapshots/my_backup", "compress": true } }'
elasticsearchのノードが持っているsnapshotの情報を取得する
curl -XGET 'http://localhost:9200/_snapshot/?pretty' # or curl -XGET 'http://localhost:9200/_snapshot/_all?pretty'
スナップショットをとる
curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"
スナップショットをとっている間、検索やインデックスの追加処理がブロックされることはない。 ただし、スナップショット作成中にインデックスの更新があっても、その変更分はスナップショットに含まれないことがある。 (もちろんスナップショットはその瞬間のものだから)
curl -XPUT "localhost:9200/_snapshot/my_backup/snapshot_201408211530?wait_for_completion=true"
スナップショットからリストアする
curl -XPOST "localhost:9200/_snapshot/my_backup/snapshot_201408211530/_restore" -d '{ "ignore_unavailable": true, "include_global_state": false }'
注意:リストアするにはインデックスをクローズしないといけない。
スナップショット復元後には差分のインデックス更新をする必要がある。
これは運用によって異なるけどelasticsearch-railsを使っているなら
Modelのupdated_at
を見て更新の必要があるレコードを調べてインデックスしなおせばいいと思う。
shardの再配置を無効にする
ドキュメントによると、I/Oで遅くなるのを避けるために、shardの再配置を無効にすることが書かれている。
curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.enable" : "none" } }'
これでshardの再配置は無効になる。
追記 (2015/10/22)
elasticsearch 1.6以上を使っている場合、shardの再配置を無効にしなくてもデフォルトで5分間は同期が無効になる。
もし手動で再同期をしたい場合は下のコマンドを発行する。
curl -XPOST localhost:9200/_all/_flush/synced
(追記ここまで)
ノードをシャットダウンする
再配置を無効にしたら、1つのノードをシャットダウンする。
curl -XPOST 'http://localhost:9200/_cluster/nodes/_local/_shutdown'
ここで、すべてのshardが今残っているノードにちゃんと再配置されているか確認する。 うまく動いているならちゃんとshardは再配置される。
ちゃんと再配置されていないまま、この先に進むとインデックスを失う恐れがある。
また、動かしているアプリケーションからも確認してうまく動いていることを確認しておく。
アップグレード
Debianを使っていてapt
でインストールしているなら、source.list
を書き換えてアップグレードする。
他のパッケージマネージャーを使っている場合も似たようにアップグレードできると思う。
apt-get update apt-get upgrade elasticsearch
設定ファイルに差分がある場合はこのタイミングで調整が必要になる。
今回の場合は、JSONPに関するオプションが追加されていた。 JSONPは1.3でセキュリティの都合上、デフォルト無効になっている。
再起動
アップグレード後、うまく起動したら再度クラスタの仲間にする。 何も問題がなければ、新しいバージョンになっても仲良くしてくれる。
shardの再配置を有効にする
curl -XPUT localhost:9200/_cluster/settings -d '{ "transient" : { "cluster.routing.allocation.enable" : "all" } }'
うまくいっていればこれでshardはうまく再配置されるはず。
elasticsearch-headなどを使って、ちゃんとshardが再配置されるのを確認する。
何も問題なければアップグレード作業は終わり。他のノードも同じようにバージョンアップすればよい。
最後に
今回はここまで。
手順通りに行って問題がないのが一番だけど、始めての作業の場合は色々と予期せぬ問題が起こるかもしれない。
今回の手順ではシャットダウンがあるので、クライアントライブラリがうまく切り替えをしてくれることを確認しておかないと、サービスが停止してしまう。
次回はfailoverの話をしてみたいので、elasicsearchのrubyクライアントライブラリ「elasticsearch-ruby」の話をやるかも。