Amazon Elasticsearch Service
開発者ガイド (API バージョン 2015-01-01)

Amazon Elasticsearch Service インデックススナップショットの使用

スナップショットはクラスターのデータと状態のバックアップです。状態には、クラスター設定、ノード情報、インデックス設定、シャードの割り当てなどが含まれます。

スナップショットを取得すると、Amazon Elasticsearch Service ドメイン間でデータを移行する場合や、障害から復旧する場合に便利です。このサービスでは、Amazon ES ドメインと自己管理型 Elasticsearch クラスターの両方で作成されたスナップショットからの復元がサポートされています。

自動スナップショットの設定 で説明されているように、Amazon ES はドメインでプライマリインデックスシャードのスナップショットを毎日作成します。サービスでは、事前設定された Amazon S3 バケットに最大 14 個のスナップショットが最大 30 日間保存されます。追加料金はかかりません。これらのスナップショットを使用すると、ドメインを復元することができます。

クラスターが赤い状態になっても問題を解決しないと、16 日後に自動化されたスナップショットが失われ始めます。トラブルシューティングステップについては、「赤のクラスター状態」を参照してください。

自動スナップショットを使用して新しいドメインに移行することはできません。自動スナップショットは、特定のドメイン内からの読み取り専用です。移行を実行するには、独自のリポジトリ (S3 バケット) に保存された手動スナップショットを使用する必要があります。手動スナップショットには標準の S3 料金が適用されます。

ヒント

インデックスやスナップショットの管理には Curator などのツールが便利です。pip を使用して Curator をインストールします。

pip install elasticsearch-curator

Curator では、複雑なクラスターでの管理を簡素化するのに役立つ、高度なフィルター機能が提供されます。Amazon ES は Elasticsearch バージョン 5.1 以降で実行されているドメインでの Curator をサポートしています。Curator はコマンドラインインターフェース (CLI) または Python API として使用できます。CLI を使用する場合は、コマンドラインで認証情報をエクスポートして curator.yml を次のように設定します。

client: hosts: search-my-domain.us-west-1.es.amazonaws.com port: 443 use_ssl: True aws_region: us-west-1 aws_sign_request: True ssl_no_validate: False timeout: 60 logging: loglevel: INFO

Python API を使用する Lambda 関数の例については、「Curator を使用した Amazon Elasticsearch Service でのデータの更新」を参照してください。

手動スナップショット前提条件

インデックススナップショットを手動で作成するには、IAM および Amazon S3 を使用して作業する必要があります。スナップショットの撮影を試す前に、次の前提条件を満たしていることを確認します。

前提条件 説明
S3 バケット

Amazon ES ドメインの手動スナップショットを保存します。バケットの名前を書き留めておきます。これは 2 つの場所で必要になります。

  • IAM ロールにアタッチされた IAM ポリシーの Resource ステートメント

  • スナップショットリポジトリの登録に使用する Python クライアント

詳細については、Amazon Simple Storage Service 入門ガイド の「バケットの作成」を参照してください。

重要

Glacier ライフサイクルルールをこのバケットに適用しないでください。手動スナップショットは、Glacier ストレージクラスをサポートしていません。

IAM ロール

Amazon Elasticsearch Service に権限を委任します。このドキュメントの残りの部分では、このロールを TheSnapshotRole と呼びます。

次の例にあるように、ロールの信頼関係は Principal ステートメントの Amazon Elasticsearch Service を指定する必要があります。

{ "Version": "2012-10-17", "Statement": [{ "Sid": "", "Effect": "Allow", "Principal": { "Service": "es.amazonaws.com" }, "Action": "sts:AssumeRole" }] }

ロールには、次のポリシーがアタッチされている必要があります。

{ "Version": "2012-10-17", "Statement": [{ "Action": [ "s3:ListBucket" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::s3-bucket-name" ] }, { "Action": [ "s3:GetObject", "s3:PutObject", "s3:DeleteObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::s3-bucket-name/*" ] } ] }

詳細については、IAM ユーザーガイド の「カスタマー管理ポリシーの作成」と「管理ポリシーのアタッチ」を参照してください。

アクセス許可

スナップショットリポジトリを登録するには、IAM ロールを引き受けることができる必要があります。さらに、es:ESHttpPut アクションへのアクセスも必要です。アクセスを提供する一般的な方法は、次のポリシーをアカウントにアタッチすることです。

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "iam:PassRole", "Resource": "arn:aws:iam::123456789012:role/TheSnapshotRole" }, { "Effect": "Allow", "Action": "es:ESHttpPut", "Resource": "arn:aws:es:region:123456789012:domain/my-domain/*" } ] }

アカウントに TheSnapshotRole を引き受ける iam:PassRole 権限がない場合、以下の一般的なエラーが発生することがあります。

$ python register-repo.py {"Message":"User: arn:aws:iam::123456789012:user/MyUserAccount is not authorized to perform: iam:PassRole on resource: arn:aws:iam::123456789012:role/TheSnapshotRole"}

手動スナップショットレポジトリの登録

手動インデックススナップショットを撮る前に、Amazon Elasticsearch Service を使用してスナップショットレポジトリを登録する必要があります。この 1 回限りのオペレーションでは、「TheSnapshotRole」で説明されているように、手動スナップショット前提条件 へのアクセスが許可された認証情報を使用して AWS リクエストを署名する必要があります。

curl は AWS リクエスト署名をサポートしていないため、これを使用してこのオペレーションを実行することはできません。代わりに、サンプル Python クライアントPostman、または他の方法を使用し、署名付きリクエストを送信してスナップショットリポジトリを登録します。リクエストは以下のような形式です。

PUT https://elasticsearch-domain.region.es.amazonaws.com/_snapshot/my-snapshot-repo { "type": "s3", "settings": { "bucket": "s3-bucket-name", "region": "region", "role_arn": "arn:aws:iam::123456789012:role/TheSnapshotRole" } }

スナップショットのディレクトを登録する操作は 1 回限りですが、1 つのドメインから別のドメインに移行するには、古いドメインと新しいドメインで同じスナップショットレポジトリを登録する必要があります。

重要

us-east-1 リージョンに S3 バケットがある場合は、"endpoint": "s3.amazonaws.com" の代わりに "region": "us-east-1" を使用する必要があります。

スナップショットリポジトリの S3 で管理されたキーによるサーバー側の暗号化を有効にするには、"settings" JSON に "server_side_encryption": true を追加します。

ドメインが VPC に存在する場合は、リクエストが正常にスナップショットレポジトリに登録するようにお使いのコンピューターが VPC に接続されていることが必要です。VPC へのアクセスはネットワーク構成によって異なりますが、VPN あるいは社内ネットワークへの接続を含む場合がよくあります。Amazon ES ドメインにアクセスできるかを確認するには、ウェブブラウザで https://your-vpc-domain.region.es.amazonaws.com を開き、デフォルトの JSON 応答を受信していることを確認します。

Python クライアントのサンプリング

次のサンプルの Python コードを、register-repo.py などの Python ファイルとして保存します。クライアントでは、AWS SDK for Python (Boto3)リクエストおよび requests-aws4auth パッケージが必要になります。クライアントには、他のスナップショットオペレーションのコメントアウトされた例が含まれています。

ヒント

Java ベースのコードサンプルは、「HTTP リクエストの署名」で入手できます。

コード内で、次の変数を更新する必要があります。hostregionpath、および payload

import boto3 import requests from requests_aws4auth import AWS4Auth host = '' # include https:// and trailing / region = '' # e.g. us-west-1 service = 'es' credentials = boto3.Session().get_credentials() awsauth = AWS4Auth(credentials.access_key, credentials.secret_key, region, service, session_token=credentials.token) # Register repository path = '_snapshot/my-snapshot-repo' # the Elasticsearch API endpoint url = host + path payload = { "type": "s3", "settings": { "bucket": "s3-bucket-name", "region": "us-west-1", "role_arn": "arn:aws:iam::123456789012:role/TheSnapshotRole" } } headers = {"Content-Type": "application/json"} r = requests.put(url, auth=awsauth, json=payload, headers=headers) print(r.status_code) print(r.text) # # Take snapshot # # path = '_snapshot/my-snapshot-repo/my-snapshot' # url = host + path # # r = requests.put(url, auth=awsauth) # # print(r.text) # # # Delete index # # path = 'my-index' # url = host + path # # r = requests.delete(url, auth=awsauth) # # print(r.text) # # # Restore snapshots (all indices) # # path = '_snapshot/my-snapshot-repo/my-snapshot/_restore' # url = host + path # # r = requests.post(url, auth=awsauth) # # print(r.text) # # # Restore snapshot (one index) # # path = '_snapshot/my-snapshot-repo/my-snapshot/_restore' # url = host + path # # payload = {"indices": "my-index"} # # headers = {"Content-Type": "application/json"} # # r = requests.post(url, auth=awsauth, json=payload, headers=headers) # # print(r.text)

手動スナップショットの撮影

スナップショットは瞬時に実行されるものではありません。完了するまで時間がかかる場合があります。スナップショットが進行中の間も、ドキュメントのインデックス作成や、クラスターへの他のリクエストを行うことはできますが、新しいドキュメント (および既存のドキュメントの更新) はスナップショットに含まれません。このスナップショットには、スナップショットを開始した時点で存在していたインデックスが含まれます。

Elasticsearch スナップショットは増分です。つまり、最後にスナップショットが取得されてから変更されたデータのみ保存されます。増分のみ保存されるため、スナップショットの取得頻度が高い場合と一度限りの場合のいずれも、ディスク使用量を最小限に抑えることができます。つまり、スナップショットを 1 時間ごとに 1 週間 (合計 168 個) 取得すると、週末に 1 つのスナップショットを取得する場合よりも、使用するディスク容量は少なくなる場合があります。また、スナップショットの取得頻度が高くなるほど、完了までにかかる時間は短くなります。中には、30 分ごとにスナップショットを取得している Elasticsearch ユーザーもいます。

スナップショットを作成する際、2 つの情報を指定します。

  • スナップショットリポジトリの名前

  • スナップショットの名前

この章の例では、わかりやすく簡潔にするために、一般的な HTTP クライアントである curl を使用します。ただし、アクセスポリシーが IAM ユーザーまたはロールを指定する場合、スナップショットリクエストに署名する必要があります。サンプル Python クライアントのコメントアウトされた例を使用して、curl コマンドが使用するのと同じエンドポイントに対し、署名された HTTP リクエストを行う必要があります。

スナップショットを手動で撮影するには

  • 次のコマンドを実行して、手動でスナップショットを撮ります。

    curl -XPUT 'elasticsearch-domain-endpoint/_snapshot/repository/snapshot-name'

注記

Amazon ES ドメインの容量が大きくなると、スナップショットの撮影に必要な時間は長くなります。長時間実行しているスナップショット操作では、通常次のエラーが発生しています。504 GATEWAY_TIMEOUT通常、このエラーは無視して、操作が正常に完了するのを待ってかまいません。次のコマンドを使用して、ドメインのすべてのスナップショットの状態を確認します。

curl -XGET 'elasticsearch-domain-endpoint/_snapshot/repository/_all?pretty'

スナップショットの復元

警告

インデックスのエイリアスを使用する場合は、インデックスを削除する前に、エイリアスへの書き込みリクエストを中止します (または別のインデックスにエイリアスを切り替えます)。書き込みリクエストを中止すると、次のシナリオの回避に有効です。

  1. インデックスを削除すると、そのエイリアスも削除される。

  2. 削除したばかりのエイリアスに対する障害のある書き込みリクエストにより、エイリアスと同じ名前で新しいインデックスが作成される。

  3. 新しいインデックスとの命名の競合により、エイリアスを使用できなくなる。

エイリアスを別のインデックスに切り替えた場合は、スナップショットから復元するときに "include_aliases": false を指定します。

スナップショットを復元するには

  1. 復元するスナップショットを特定します。すべてのスナップショットレポジトリを表示するには、次のコマンドを実行します。

    curl -XGET 'elasticsearch-domain-endpoint/_snapshot?pretty'

    リポジトリを識別した後、次のコマンドを実行してすべてのスナップショットを表示します。

    curl -XGET 'elasticsearch-domain-endpoint/_snapshot/repository/_all?pretty'

    注記

    ほとんどの自動スナップショットは、cs-automated リポジトリに保存されます。ドメインで暗号化された保管時のデータは cs-automated-enc リポジトリに保存されます。検索する手動スナップショットレポジトリが表示されない場合は、ドメインにその登録をしたことを確認します。

  2. Amazon ES ドメイン内のすべてのオープンインデックスを削除または名前変更します。

    インデックスのスナップショットを復元する際に、復元先の Elasticsearch クラスターに同じ名前のインデックスが既にある場合は、復元できません。現在、Amazon ES は Elasticsearch _close API をサポートしていないため、代替手段として、次のうちいずれかを使用する必要があります。

    次の例では、ドメインの既存のインデックスをすべて削除する方法について説明しています。

    curl -XDELETE 'elasticsearch-domain-endpoint/_all'

    すべてのインデックスを復元する予定がない場合には、1 つのみを削除することもできます。

    curl -XDELETE 'elasticsearch-domain-endpoint/index-name'
  3. スナップショットを復元するには、次のコマンドを実行します。

    curl -XPOST 'elasticsearch-domain-endpoint/_snapshot/repository/snapshot/_restore'

    .kibana インデックスでの特別なアクセス許可により、すべてのインデックスの復元を試みるとすると失敗する場合があります (特に、自動スナップショットから復元を試みた場合)。次の例では、 1 つのインデックスである my-index2017-snapshot から cs-automated スナップショットレポジトリで復元します。

    curl -XPOST 'elasticsearch-domain-endpoint/_snapshot/cs-automated/2017-snapshot/_restore' -d '{"indices": "my-index"}' -H 'Content-Type: application/json'

注記

関連するインデックスに対してすべてのプライマリシャードを使用できなかった場合、スナップショットの statePARTIAL になっている可能性があります。この値は、1 つ以上のシャードからのデータが正しく保存されていないことを示します。部分スナップショットからの復元も可能ですが、不足しているインデックスの復元に古いスナップショットの使用が必要になる場合もあります。