在 Amazon Elasticsearch Service 中创建索引快照 - Amazon Elasticsearch Service
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 Amazon Web Services 服务入门

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

在 Amazon Elasticsearch Service 中创建索引快照

Amazon Elasticsearch Service (Amazon ES) 中的快照是集群的索引和状态的备份。包含集群设置、节点信息、索引设置和分片分配。

Amazon ES 快照有以下形式:

  • 自动快照仅用于集群恢复。在发生红色群集状态或数据丢失时,您可以使用它们还原您的域。有关更多信息,请参阅 。还原快照下面的。Amazon ES 将自动快照存储在预配置的 Amazon S3 存储桶中,您无需额外付费。

  • 手动快照用于群集恢复或者用于将数据从一个集群移动到另一个集群。您必须自行启动手动快照。这些快照存储在您自己的 Amazon S3 存储桶中,收取标准 S3 费用。如果您有来自自行管理的 Elasticsearch 集群的快照,则可以使用该快照迁移到 Amazon ES 域。有关更多信息,请参阅 。迁移到 Amazon Elasticsearch Service

所有 Amazon ES 域都制作自动快照,但频率在以下几种方式不同:

  • 对于运行 Elasticsearch 5.3 及更高版本的域,Amazon ES 会每小时自动制作快照,并且将最多 336 个快照保留 14 天时间。

  • 对于运行 Elasticsearch 5.1 及更低版本的域,Amazon ES 会在您指定的小时内每日自动制作快照,并且将最多 14 个快照数据保留 30 天以上时间。

如果集群进入红色状态,则所有自动快照都会失败,而集群状态仍保留。如果您在两周内未解决问题,则可能会永久丢失集群中的数据。有关问题排查步骤,请参阅红色集群状态

Prerequisites

要手动创建快照,您需要使用 IAM 和 Amazon S3。确保您满足以下先决条件,然后再尝试创建快照:

先决条件 描述
S3 存储桶

创建 S3 存储桶以存储 Amazon ES 域的手动快照。有关说明,请参阅创建存储桶中的Amazon Simple Storage Service 入门指南

记住要在以下位置使用该存储桶的名称:

  • 这些区域有:Resource附加到 IAM 角色的 IAM 策略的语句

  • 用于注册快照存储库的 Python 客户端(如果您使用此方法)

重要

请勿对此存储桶应用 S3 Glacier 生命周期规则。手动快照不支持 S3 Glacier 存储类别。

IAM 角色

创建向 Amazon ES 委派权限的 IAM 角色。有关说明,请参阅创建 IAM 角色(控制台)中的IAM 用户指南。本章剩余部分将此角色称为 TheSnapshotRole

附加 IAM 策略

将以下策略附加到TheSnapshotRole以允许访问 S3 存储桶:

{ "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 用户指南

编辑信任关系

编辑的信任关系TheSnapshotRole中指定亚马逊 ESPrincipal语句,如以下示例所示:

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

有关编辑信任关系的说明,请参阅修改角色信任策略中的IAM 用户指南

权限

要注册快照存储库,您需要能够通过TheSnapshotRole发送到 Amazon ES。还需要对 es:ESHttpPut 操作的访问权限。要授予这两个权限,请将以下策略附加到其凭证用于签署请求的 IAM 用户或角色:

{ "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/domain-name/*" } ] }

如果您的用户或角色没有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 ES 注册快照存储库,然后才能拍摄手动索引快照。此一次性操作需要您签名Amazon请求,具有允许访问的凭据TheSnapshotRole,如所述Prerequisites

第 1 步:在 Kibana 中映射快照角色(如果使用精细访问控制)

精细访问控制会在注册存储库时引入一个额外的步骤。即使您将 HTTP 基本身份验证用于所有其他目的,也需要将manage_snapshots角色分配给您的 IAM 用户或具有iam:PassRole传递权限TheSnapshotRole

  1. 导航到您的 Amazon ES 域的 Kibana 插件。您可以在 Amazon ES 控制台的域控制面板中找到 Kibana 终端节点。

  2. 从主菜单中选择安全角色,然后选择管理快照角色。

  3. 选择映射用户管理映射

  4. 添加具有传递权限的用户或角色的域 ARNTheSnapshotRole。将用户 ARN 置于用户和角色 ARN 下后端角色

    arn:aws:iam::123456789123:user/user-name
    arn:aws:iam::123456789123:role/role-name
  5. Select映射并确认用户或角色显示在映射用户

第 2 步:注册一个存储库

要注册快照存储库,请向 Amazon ES 域终端节点发送 PUT 请求。您不能使用curl执行此操作,因为它不支持Amazon请求签名。请改用示例 Python 客户端Postman 或某种其他方式发送已签名请求以注册快照存储库。

请求采用以下格式:

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

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

对快照存储库进行加密

您目前无法使用密钥管理服务 (KMS) 主密钥来加密手动快照,但可以使用服务器端加密 (SSE) 保护它们。

要为您用作快照存储库的存储桶启用 SSE,请将添加"server_side_encryption": true添加到"settings"块。有关更多信息,请参阅 。通过使用 Amazon S3 托管加密密密密钥的服务器端加密保护数据中的Amazon Simple Storage Service 用户指南

或者,您可以在用作快照存储库的 S3 存储桶上使用客户主密钥 (CMK) 进行服务器端加密。

将数据迁移到另一个域

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

由于其他原因,迁移到新域或向多个域注册同一存储库时,请考虑以下准则:

  • 在新域中注册存储库时,添加"readonly": true添加到"settings"块。此设置可防止您意外覆盖旧域中的数据。

  • 如果您要将数据迁移到不同区域中的域(例如,从位于 us-east-2 的旧域和存储桶到 us-west-2 中的新域),则在发送 PUT 请求时可能会看到此 500 错误:

    The bucket is in this region: us-east-2. Please use this region to retry the request.

    如果您遇到此错误,请尝试将"region": "us-east-2"替换为"endpoint": "s3.amazonaws.com",然后重试请求。

使用示例 Python 客户端

Python 客户端比简单的 HTTP 请求更容易自动化,并且具有更好的可重用性。如果您选择使用此方法注册快照存储库,请将下面的示例 Python 代码保存为 Python 文件,如register-repo.py。客户端需要 Amazon SDK for Python (Boto3)requestsrequests-aws4auth 程序包。客户端包含其他快照操作的带注释示例。

提示

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

更新示例代码中的以下变量: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-name' # 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 snapshot (all indices except Kibana and fine-grained access control) # # path = '_snapshot/my-snapshot-repo/my-snapshot/_restore' # url = host + path # # payload = { # "indices": "-.kibana*,-.opendistro_security", # "include_global_state": False # } # # headers = {"Content-Type": "application/json"} # # r = requests.post(url, auth=awsauth, json=payload, headers=headers) # # 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 命令使用的同一终端节点。

要创建手动快照,请执行以下步骤:

  1. 如果当前正在制作快照,则您无法制作快照。要进行检查,请运行以下命令:

    curl -XGET 'elasticsearch-domain-endpoint/_snapshot/_status'
  2. 运行以下命令来创建手动快照:

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

创建快照所需的时间会随着 Amazon ES 域大小的增长而增加。长时间运行的快照操作有时会遇到以下错误:504 GATEWAY_TIMEOUT。 通常情况下,您可以忽略这些错误并等待操作成功完成。运行以下命令验证您的域中所有快照的状态:

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

还原快照

警告

如果您使用索引别名,请在删除别名的索引前停止对别名的写入请求,或将别名切换到另一个索引。停止写入请求有助于避免以下情景:

  1. 您删除某个索引,同时会删除它的别名。

  2. 对于现已删除的别名的错误写入请求会创建一个与别名同名的新索引。

  3. 由于与新索引的命名冲突,您无法再使用别名。

如果将别名切换到其他索引,请在从快照中还原时指定 "include_aliases": false

要还原快照,请执行以下步骤:

  1. 确定要还原的快照。要查看所有快照存储库,请运行以下命令:

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

    在确定存储库后,您可以运行以下命令查看所有快照:

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

    大多数自动快照存储在 cs-automated 存储库中。如果您的域对静态数据进行加密,这些快照将存储在cs-automated-enc存储库。如果您没有看到要查找的手动快照存储库,请确保您注册时间添加到域。

  2. (可选)如果集群上的索引与快照中的索引之间存在命名冲突,则删除或重命名 Amazon ES 域中的一个或多个索引。您不能将索引的快照还原到已包含同名索引的 Elasticsearch 群集。

    如果您有索引命名冲突,您可以使用以下选项:

    • 删除现有 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-name/snapshot-name/_restore'

    由于针对 Kibana 和精细访问控制索引的特殊权限,尝试还原所有索引时可能会失败,尤其是当您尝试从自动快照还原时。以下示例通过 my-index 快照存储库中的 2020-snapshot 来只还原一个索引 cs-automated

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

    或者,您可能需要还原所有索引除外Kibana 和精细出入控制指数:

    curl -XPOST 'elasticsearch-domain-endpoint/_snapshot/cs-automated/2020-snapshot/_restore' -d '{"indices": "-.kibana*,-.opendistro_security"}' -H 'Content-Type: application/json'
注意

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

删除手动快照

要删除手动快照,请运行以下命令:

DELETE _snapshot/repository-name/snapshot-name

通过索引状态管理自动执行快照

您可以使用索引状态管理 (ISM)snapshot操作可根据索引的年龄、大小或文档数量的变化自动触发索引快照。有关使用snapshot操作,请参阅示例策略

将 Curator 用于快照

一些用户找到了 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 中轮换数据