Elastic Stack でバックアップ（スナップショット）／リストア



本番システムでは、ログデータのバックアップ／リストア、ストレージ確保は必須事項です。
Elastic Stackを実用するにあたってやり方を勉強しました。

## 環境

- OS: Win 7 Pro 64bit
- Elasticsearch: 5.0.0 rc-1
- Kibana: 5.0.0 rc-1

操作は全てKibanaコンソールで実施しました。
![28.png](https://qiita-image-store.s3.amazonaws.com/0/68978/e5685b8b-c366-b919-a82d-dc1f59215180.png)


## Elastic Stackでは

バックアップデータを保存するための「リポジトリ」を作成し、
そこに「スナップショット」を撮ることでデータをバックアップできるそうです。
スナップショットは「リストア」できるそうです。

ということは、ストレージの空きを確保するには、”古いデータに絞ってスナップショットを撮り、当該データを削除”できれば良さそうです。

さっそくやっていきましょう。


## リポジトリの作成

### リポジトリの場所を設定ファイルに記載

リポジトリを配置するルートを設定します。

```js:elasticsearch.yml
・・・（最終行）
path.repo: ["C:\\dev\\elastic-rc1\\elasticsearch-5.0.0-rc1\\repositories"]
```

### リポジトリ作成

- リクエスト

```js
PUT /_snapshot/myrepo
{
  "type": "fs",
  "settings": {
    "location": "myrepo"
  }
}
```

- 結果

```js
{
  "acknowledged": true
}
```

次のようなフォルダができました。

```js
C:\dev\elastic-rc1\elasticsearch-5.0.0-rc1\repositories\myrepo
```

### リポジトリの確認

- リクエスト

```js
GET /_snapshot
```

- 結果

```js
{
  "myrepo": {
    "type": "fs",
    "settings": {
      "location": "myrepo"
    }
  }
}
```

> しかし、Kibanaコンソールは`/_snapshot`とかのURIをサジェストしてくれるから、便利ね。

> さらに、ここで`DELETE /_snapshot/myrepo`をたたくと、リポジトリがちゃんと消える。さすがRESTful。

### リポジトリのベリファイ

というのができるらしいので実行してみた。

- リクエスト

```js
POST /_snapshot/myrepo/_verify
```

- 結果

```js
{
  "nodes": {
    "plCY4gHHRFeM-zmDY4qBtw": {
      "name": "plCY4gH"
    }
  }
}
```

なるほどわからん。

## スナップショットの取得

### おもむろに（全体）

- リクエスト

```js
PUT /_snapshot/myrepo/snapshot_1?wait_for_completion=true
```

- 結果（時間かかります）

```js
{
  "snapshot": {
    "snapshot": "snapshot_1",
    "uuid": "xAXb0VBlSieLkVpFsgpr2Q",
    "version_id": 5000051,
    "version": "5.0.0-rc1",
    "indices": [
      "logstash-2016.10.18",
      "logstash-2016.10.26",
      "logstash-2016.10.31",
      ".kibana"
    ],
    "state": "SUCCESS",
    "start_time": "2016-11-01T07:36:10.370Z",
    "start_time_in_millis": 1477985770370,
    "end_time": "2016-11-01T07:36:19.250Z",
    "end_time_in_millis": 1477985779250,
    "duration_in_millis": 8880,
    "failures": [],
    "shards": {
      "total": 16,
      "failed": 0,
      "successful": 16
    }
  }
}
```
8880ミリ秒かかってるみたいです。

フォルダは`snapshot_1`ができていると思いきや、わけわからんことなってました。

```js:\repositories\myrepo\
indices （←フォルダ）
index.latest
index-0
meta-xAXb0VBlSieLkVpFsgpr2Q.dat
snap-xAXb0VBlSieLkVpFsgpr2Q.dat
```

### 古いデータだけ

上記結果で、indicesが`logstash-2016.10.18`、`logstash-2016.10.26`、`logstash-2016.10.31`と日ごとに分かれています。
これで日単位のスナップショットが撮れそうです。

- リクエスト

```js
PUT /_snapshot/myrepo/snapshot_2
{
  "indices": "logstash-2016.10.31",
  "ignore_unavailable": true,
  "include_global_state": false
}
```

- 結果

```js
{
  "accepted": true
}
```

やけにあっさり終わりましたが・・・

- リクエスト

```js
GET /_snapshot/myrepo/snapshot_2
```

- 結果

```js
{
  "snapshots": [
    {
      "snapshot": "snapshot_2",
      "uuid": "CULBcckJSzG1zqW-FC_JbA",
      "version_id": 5000051,
      "version": "5.0.0-rc1",
      "indices": [
        "logstash-2016.10.31"
      ],
      "state": "SUCCESS",
      "start_time": "2016-11-01T07:45:52.381Z",
      "start_time_in_millis": 1477986352381,
      "end_time": "2016-11-01T07:45:52.958Z",
      "end_time_in_millis": 1477986352958,
      "duration_in_millis": 577,
      "failures": [],
      "shards": {
        "total": 5,
        "failed": 0,
        "successful": 5
      }
    }
  ]
}
```

## 古いデータを削除

10/26のデータを削除しましょう。
![23.png](https://qiita-image-store.s3.amazonaws.com/0/68978/b9a7a15d-af07-199f-f41f-fd7d68cd66a4.png)

削除前のデータサイズはこちら。
![27.png](https://qiita-image-store.s3.amazonaws.com/0/68978/bba16f33-ad44-8efa-f0cd-ff0450502445.png)

- リクエスト

```js
DELETE /logstash-2016.10.26
```

- 結果

```js
{
  "acknowledged": true
}
```

10/26のデータが削除されました。これでストレージが空きました。
![24.png](https://qiita-image-store.s3.amazonaws.com/0/68978/4931ee14-f229-0515-fe3f-aad58dd7b80f.png)
![25.png](https://qiita-image-store.s3.amazonaws.com/0/68978/84772e97-e4ab-3170-de5c-9edc225793a9.png)


## スナップショットのリストア

リストアできるか確認しましょう。
全体のスナップショットから、特定のインデックスだけ復元します。

- リクエスト

```js
POST /_snapshot/myrepo/snapshot_1/_restore
{
  "indices": "logstash-2016.10.26"
}
```

- 結果

```js
{
  "accepted": true
}
```

10/26のデータが帰ってきました！
![26.png](https://qiita-image-store.s3.amazonaws.com/0/68978/1f8f7721-366d-f6a4-c871-4e565eec93f3.png)

ストレージも消費しています。
![27.png](https://qiita-image-store.s3.amazonaws.com/0/68978/30097d0a-3796-5d43-a10b-c4d5920dcbde.png)


ちなみに、存在するインデックスを復元しようとすると、次のようなエラーになります。

```js
{
  "error": {
    "root_cause": [
      {
        "type": "snapshot_restore_exception",
        "reason": "[myrepo:snapshot_1/xAXb0VBlSieLkVpFsgpr2Q] cannot restore index [.kibana] because it's open"
      }
    ],
    "type": "snapshot_restore_exception",
    "reason": "[myrepo:snapshot_1/xAXb0VBlSieLkVpFsgpr2Q] cannot restore index [.kibana] because it's open"
  },
  "status": 500
}
```

## まとめ

1か月以上前などの古いインデックスは、スナップショットを撮ってから削除することで、ストレージを確保できますね。
リストアも可能です。

スナップショットのファイルを、ファイルシステムとして移動するわけではなさそうなので、NAS等にリポジトリを作るのがベストなんでしょうかね？

ちなみにElasticsearchバージョンアップのためのバックアップ・リストアについては、[スナップショットの互換性に制限](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html#modules-snapshots)があるので、確認したほうがよいでしょう。


## おまけ：path.repo

マニュアルみると、

```js
path.repo: ["/mount/backups", "/mount/longterm_backups"]
```
みたいにパスの省略ができるっぽい。
リプレース的に使えるか？やってみた。

### その１

```js:elasticsearch.yml
path.repo: ["repositories", "C:\\dev\\elastic-rc1\\elasticsearch-5.0.0-rc1\\repositories"]
```

＋

```js
PUT /_snapshot/myrepo1
{
  "type": "fs",
  "settings": {
    "location": "repositories/myrepo1
  }
}
```

=

```js
C:\dev\elastic-rc1\elasticsearch-5.0.0-rc1\repositories\repositories\myrepo1
```

oh...

### その２

```js:elasticsearch.yml
path.repo: ["C:\\repositories", "C:\\dev\\elastic-rc1\\elasticsearch-5.0.0-rc1\\repositories"]
```

OR

```js:elasticsearch.yml
path.repo: ["/repositories", "C:\\dev\\elastic-rc1\\elasticsearch-5.0.0-rc1\\repositories"]
```

=
Elasticsearchを起動したタイミングで、次のフォルダができた。

```js
C:\repositories
```

その１はなんとなく理解できるけど、その２はマニュアル通りになってなさそうで気持ち悪い。Windowsだけか？
とりあえず、`path.repo`はリポジトリにしたいディレクトリだけ指定するのがよさそう。

## 参考

[Snapshot And Restore | Elasticsearch Reference [5.0] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-snapshots.html)