なんかかきたい

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

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を使って簡単にスナップショットを取れる。

Snapshot And Restore

とりあえずざっくりやるならファイルシステムに作ってもいいと思うので、ファイルシステムにスナップショットを作る手順をまとめます。

スナップショットのためのディレクトリを作る

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」の話をやるかも。