Elasticsearch2.3.0のバックアップとリストア

# 概要

Elasticsearchを運用していてうっかりデータを消して悲惨なことになった（本番環境ではないですが）ので、
Elasticsearchのインデックスのバックアップ及びリストア方法についてまとめます。

個人的な備忘メモとなりますので、詳細は本家のガイドラインを参照してください。
https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html

# 環境情報

Elasticsearch: 2.3.0

# リポジトリ準備

スナップショットの作成、リストアを行う前にスナップショット用のリポジトリを用意します。
今回はリポジトリとして共有ファイルシステムを利用しますが、公式のプラグインを利用することでバックエンドとしてAmazon S3やAzure Storage Repositoryを利用することもできます。

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html#_repository_plugins

## ディレクトリ作成

所有者と所有グループはElasticsearch用のユーザ、グループを指定します。（今回は`elasticsearch`）

```bash
$ sudo mkdir -p /var/elasticsearch/snapshot
$ sudo chown -R elasticsearch:elasticsearch /var/elasticsearch
```

### リポジトリ設定

共有ファイルシステムをリポジトリとして使用する場合、マスタノード、データノードの全てで同じロケーションを指定する必要があります。
このロケーションは`elasticsearch.yml`の`path.repo`で指定します。

```yaml:/etc/elasticsearch.yml
path.repo: ["/var/elasticsearch/snapshot"]
```

### リポジトリ登録

Elasticsearchにリポジトリを登録します。

```bash
$ curl -XPUT 'http://localhost:9200/_snapshot/snapshot1' -d '{
    "type": "fs",
    "settings": {
        "location": "/var/elasticsearch/snapshot/snapshot1",
        "compress": true
    }
}'
```

`location`にはスナップショットのリポジトリ（今回はサブディレクトリとしてsnapshot1を指定しています。）を指定します。
`compress`が`true`の場合、スナップショットは圧縮して保存されます。


# スナップショット作成

Elasticsearchはクラスタ単位もしくはインデックス単位である時点のスナップショットを作成することができます。

## 作成

今回はインデックス`index-2016.04.08`を指定してスナップショット`snapshot-2016.04.08`を作成します。
スナップショットをとっている間、検索やインデックスの追加処理がブロックされることはありません。

```
$ curl -XPUT 'http://localhost:9200/_snapshot/snapshot1/snapshot-2016.04.08?wait_for_completion=true' -d '{
    "indices": "index-2016.04.08",
    "ignore_unavailable": true,
    "include_global_state": false
}'
```

`wait_for_completion`に`true`を指定することでスナップショットの作成完了を待ちます。
オプションは下記のとおりとなります。

| オプション              | 説明                                                                                                    |
|----------------------|------------------------------------------------------------------------------------------------------------|
| indices              | スナップショットを作成するインデックス                                                                     |
| ignore_unavailable   | 無効なインデックスを無視するかどうか<br>確認していないが恐らくcloseされているインデックス等は無視されるのかと |
| include_global_state | クラスタのGlobal Stateをスナップショットに含めるかどうか                                                   |

## 確認

Elasticsearchからスナップショットを確認します。

```
$ curl -XGET 'http://localhost:9200/_snapshot/snapshot1/snapshot-2016.04.08'
```

作成されていることがわかります。

```json
{
  "snapshots": [
    {
      "snapshot": "snapshot-2016.04.08",
      "version_id": 2030099,
      "version": "2.3.0",
      "indices": [
        "index-2016.04.08"
      ],
      "state": "SUCCESS",
      "start_time": "2016-04-08T10:10:26.452Z",
      "start_time_in_millis": 1460110226452,
      "end_time": "2016-04-08T10:10:27.130Z",
      "end_time_in_millis": 1460110227130,
      "duration_in_millis": 678,
      "failures": [],
      "shards": {
        "total": 5,
        "failed": 0,
        "successful": 5
      }
    }
  ]
}
```

物理的なリポジトリも確認してみます。確かにスナップショットが作成されていますね。

```bash
$ ls -ltr /var/elasticsearch/snapshot/snapshot1/
合計 16
drwxr-xr-x 3 elasticsearch elasticsearch 4096  4月  8 17:40 indices
-rw-r--r-- 1 elasticsearch elasticsearch  103  4月  8 19:10 meta-snapshot-2016.04.08.dat
-rw-r--r-- 1 elasticsearch elasticsearch  195  4月  8 19:10 snap-snapshot-2016.04.08.dat
-rw-r--r-- 1 elasticsearch elasticsearch   37  4月  8 19:10 index
```

# リストア

インデックスを指定してリストアします。

```
$ curl -XPOST 'http://localhost:9200/_snapshot/snapshot1/snapshot-2016.04.08/_restore' -d '{
	"indices": "index-2016.04.08",
    "ignore_unavailable": "true",
    "include_global_state": false
}'
```