Amazon Elasticsearch Service の自動スナップショットからのリストアを試してみた

Elasticsearch Service

ども、藤本です。

先日、Amazon Elasticsearch Service で Elasticsearch 5.5 が利用可能となりました。

また 5.5 の利用以外にも Amazon Elasticsearch Service としてのアップデートがあり、その中の一つに自動スナップショットのユーザー利用がありました。上記エントリ時は速報でスナップショットデータがなかったので試すことができませんでしたが、週末放置してスナップショットデータができたので早速試してみました。

概要

Amazon Elasticsearch Service は AWS のマネージドサービスでスナップショットは日次で自動で取得してくれます。ただ今までは自動取得したスナップショットから復元する場合、自身では実施できず、サポートへ依頼した上で AWS マターで復元が実施されます。S3 への手動スナップショットも実施できますが、Elasticsearch 自身でスナップショットのスケジューリング機能を持っていないため、Curator や独自スクリプトで外部で実装する必要がありました。それが今回のアップデートで任意のタイミングでユーザーの操作により自動スナップショットから復元可能となりました。データ破損時や、障害発生時に AWS への連絡や AWS の作業を待たずに即時に復元に取り掛かれるのは嬉しいです。復元操作は Elasticsearch 標準の WebAPI をリクエストして、実行できます。

試してみた

※ コードブロックは全て Kibana の Console から実行したものとなります。

スナップショットデータを見てみる

まずはどのように登録されているのか Elasticsearch の API をリクエストしてみて確認してみましょう。まずはリポジトリを確認してみます。

1
2
3
4
5
6
GET _snapshot
{
  "cs-automated": {
    "type": "s3"
  }
}

cs-automatedというリポジトリ名で S3 バケットをリポジトリとしています。本来であれば、S3 バックアップはバケット名、リージョン名を登録し、確認することができますが、Amazon Elasticsearch Service によってマスクされているようです。

次に登録されているスナップショットデータを確認してみます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
GET _snapshot/cs-automated/_all
{
  "snapshots": [
    {
      "snapshot": "2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94",
      "uuid": "QIjq9KpMSDqHkQSdXXClBA",
      "version_id": 5050299,
      "version": "5.5.2",
      "indices": [
        ".kibana",
        "user"
      ],
      "state": "SUCCESS",
      "start_time": "2017-09-09T00:49:13.820Z",
      "start_time_in_millis": 1504918153820,
      "end_time": "2017-09-09T00:49:17.420Z",
      "end_time_in_millis": 1504918157420,
      "duration_in_millis": 3600,
      "failures": [],
      "shards": {
        "total": 6,
        "failed": 0,
        "successful": 6
      }
    },
    {
      "snapshot": "2017-09-10t00-49-14.0e317692-70ff-4476-8345-75d8493e4bea",
:
      "state": "SUCCESS",
      "start_time": "2017-09-10T00:49:14.964Z",
      "start_time_in_millis": 1505004554964,
:
    },
    {
      "snapshot": "2017-09-11t00-49-07.4afdf10b-8ae1-41cd-9671-30eeb5b1cd64",
:
      "state": "SUCCESS",
      "start_time": "2017-09-11T00:49:08.021Z",
      "start_time_in_millis": 1505090948021,
:
    }
  ]
}

金曜日に作成したエンドポイントなので、土日月と 3日間のスナップショットが取得されています。自動スナップショット作成時間はデフォルトの0:00UTCを指定しているので、毎日 0時台となる 0:49UTC に取得しています。データは非常に少ないので数秒で取得が完了しています。

自動スナップショットのデータから復元する

まずは同じインデックス名でインデックスをリストアします。Elasticsearch のリストアは Open ステータスのインデックスに対する上書きは実施できません。既に存在する場合は Close ステータスのインデックスであれば上書きできますが、Amazon Elasticsearch Service は_close API を提供していないため、インデックスを削除してからリストアします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
### リストア前のインデックス一覧(リストア状態のインデックスがある状態)
GET _cat/indices
yellow open user    E3Cxs7gZTNWEQZi59HNLXw 5 1 1 0 4.4kb 4.4kb
yellow open .kibana ttj8_dU0ThaFnqYlLwsodg 1 1 1 0 3.2kb 3.2kb
 
### リストアを試みるも同名のインデックスがあるので失敗
POST /_snapshot/cs-automated/2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94/_restore
{
  "error": {
    "root_cause": [
      {
        "type": "snapshot_restore_exception",
        "reason": "[cs-automated:2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94/QIjq9KpMSDqHkQSdXXClBA] cannot restore index [.kibana] because it's open"
      }
    ],
    "type": "snapshot_restore_exception",
    "reason": "[cs-automated:2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94/QIjq9KpMSDqHkQSdXXClBA] cannot restore index [.kibana] because it's open"
  },
  "status": 500
}
 
### インデックスを一度全部削除
DELETE *
{
  "acknowledged": true
}
 
### インデックス一覧(何もない)
GET _cat/indices
 
### リストア成功
POST /_snapshot/cs-automated/2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94/_restore
{
  "accepted": true
}
 
### インデックスリストア
GET _cat/indices
yellow open .kibana 6pdS4PE-RzO4mYfXBjkljQ 1 1 1 0 3.2kb 3.2kb
yellow open user    Z_QfLv1fTRuulVN1P_xPSA 5 1 1 0 4.4kb 4.4kb

復元されました。

別名インデックスで復元する

ダウンタイムを許容できない場合、別インデックスとしてリストアして、Alias によって切り替える方法もあります。リストア時に Alias 設定するのではなく元々、Alias を設定しておいてください。Elasticsearch を利用するアプリケーションは Alias を参照するように実装してください。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
### エイリアス「alias-user」はインデックス「user」に向いている
GET _aliases
{
  "user": {
    "aliases": {
      "alias-user": {}
    }
  },
  ".kibana": {
    "aliases": {}
  }
}
 
### スナップショットのインデックス「user」をインデックス「restore_user」としてリストア
POST /_snapshot/cs-automated/2017-09-09t00-49-13.d57ae0fe-ed9a-4917-b364-c8648b35ca94/_restore
{
  "indices": "user",
  "rename_pattern": "user",
  "rename_replacement": "restore_user"
}
 
### エイリアスの向き先を変更(作成/削除)
POST _aliases
{
  "actions": [
    {
      "remove": {
        "index": "user",
        "alias": "alias-user"
      }
    },
    {
      "add": {
        "index": "restore_user",
        "alias": "alias-user"
      }
    }
  ]
}
 
### エイリアス「alias-user」がインデックス「restore_user」に向き先が変わった
GET _aliases
{
  "restore_user": {
    "aliases": {
      "alias-user": {}
    }
  },
  "user": {
    "aliases": {}
  },
  ".kibana": {
    "aliases": {}
  }
}
 
### インデックス「restore_user」が読み出される
GET alias-user
{
  "restore_user": {
    "aliases": {
      "alias-user": {}
    },
    "mappings": {
:
    },
    "settings": {
:
    }
  }
}

といった感じでアプリケーション側の変更することなく、参照するインデックスを変更することができます。

他に気になったので試してみたこと

自動スナップショットリポジトリにスナップショットしてみるができなかった

自動スナップショットリポジトリに任意のスナップショット取得できるか試してみましたができませんでした。任意のインデックスのみ、任意のタイミングで取得したい場合は今まで通り手動で S3 スナップショットリポジトリを利用する必要があります。

1
2
3
4
PUT /_snapshot/cs-automated/snapshot_1
{
  "Message": "Your request: '/_snapshot/cs-automated/snapshot_1' is not allowed."
}

手動スナップショットは下記ブログエントリの 1章を参照。

まとめ

いかがでしたでしょうか? 自動スナップショットを自由に利用できることは嬉しいですね!