Amazon Elasticsearch Service
开发人员指南 (API 版本 2015-01-01)
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 Amazon AWS 入门

使用 Amazon Elasticsearch Service 索引快照

快照是群集的数据和状态的备份。状态包含集群设置、节点信息、索引设置和分片分配。

快照提供便捷的方式来跨 Amazon Elasticsearch Service 域迁移数据和从故障中恢复。该服务支持使用在 Amazon ES 域和自管理 Elasticsearch 集群中拍摄的快照来还原。

Amazon ES 拍摄域中的主索引分片的每日自动快照,如配置自动快照中所述。此服务将多达 14 个快照存储在预配置的 Amazon S3 存储桶中不超过 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 域存储手动快照。记下存储桶的名称。在两个地方需要用到它:

  • 附加到 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/*" } ] }

如果账户没有 iam:PassRole 权限来代入 TheSnapshotRole,您可能会遇到以下常见错误:

$ 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 注册快照存储库,然后才能拍摄手动索引快照。此一次性操作需要使用允许访问 TheSnapshotRole 的凭证签发 AWS 请求,如手动快照先决条件中所述。

不能使用 curl 执行此操作,因为它不支持 AWS 请求签名。请改用示例 Python 客户端Postman 或某种其他方式发送已签名请求以注册快照存储库。此请求采用以下形式:

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

注册快照目录是一次性操作,但要从一个域迁移到另一个域,您必须在旧域和新域中注册相同的快照存储库。

重要

如果 S3 存储桶位于 us-east-1 区域,您需要使用 "endpoint": "s3.amazonaws.com" 而不是 "region": "us-east-1"

要为快照存储库启用使用 S3 托管密钥的服务器端加密,请将 "server_side_encryption": true 添加到 "settings" JSON。

如果域位于 VPC 中,则计算机必须连接到 VPC,请求才能成功注册快照存储库。访问 VPC 因网络配置而异,但很可能包括连接到 VPN 或企业网络。要检查您是否可以访问 Amazon ES 域,请在 Web 浏览器中导航到 https://your-vpc-domain.region.es.amazonaws.com 并验证您是否收到默认的 JSON 响应。

示例 Python 客户端

将下面的示例 Python 代码保存为 Python 文件,如 register-repo.py。客户端需要 适用于 Python 的 AWS 开发工具包 (Boto3)requestsrequests-aws4auth 软件包。客户端包含其他快照操作的带注释示例。

提示

签署 HTTP 请求中提供了一个基于 Java 的代码示例。

必须更新代码中的以下变量:hostregionpathpayload

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 启动快照时存在的主分片。根据快照线程池的大小,快照中可能包含时间略有不同的不同分片。

Elasticsearch 快照为增量快照,这意味着它们仅存储自上次快照成功后已更改的数据。此增量性质意味着频繁快照与不频繁快照之间的磁盘使用率差异通常极其小。换句话说,一周内每小时快照(总共 168 个快照)占用的磁盘空间比一周结束时的一个快照所占用的磁盘空间并不高多少。此外,拍摄快照的频率越高,完成快照所需的时间就更少。一些 Elasticsearch 用户每半小时拍摄一次快照。

在创建快照时指定两项信息:

  • 快照存储库的名称

  • 快照名称

为了方便和简洁起见,本章中的示例使用 curl,这是一种常见的 HTTP 客户端。但是,如果您的访问策略指定 IAM 用户或角色,您必须对快照请求进行签名。您可以使用示例 Python 客户端中的带注释示例将签名 HTTP 请求置于 curl 命令使用的同一终端节点。

手动创建快照

  • 运行以下命令来手动创建快照:

    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,因此,您必须使用以下备选项之一:

    • 删除同一个 Amazon ES 域中的索引,然后还原快照。

    • 从快照还原索引时为其重命名,之后为它们重新编制索引。

    • 将快照还原到另一个 Amazon ES 域 (只能通过手动快照实现).

    以下示例演示如何删除域的所有 现有索引:

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

    但如果您不打算还原所有索引,则可能需要仅删除一个索引:

    curl -XDELETE 'elasticsearch-domain-endpoint/index-name'
  3. 要还原快照,请运行以下命令:

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

    由于 .kibana 索引上的特殊权限,尝试还原所有索引可能会失败,尤其是当您尝试从自动快照还原时。以下示例通过 my-index 快照存储库中的 2017-snapshot 来只还原一个索引 cs-automated

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

注意

如果并非所有主分片都适用于涉及的索引,则快照的 state 可能为 PARTIAL。此值表示未成功存储至少一个分片中的数据。您仍可以从部分快照进行还原,但可能需要使用较旧的快照来还原任何缺失的索引。