Amazon Elasticsearch Service
開發人員指南 (API 版本 2015-01-01)

使用 Amazon Elasticsearch Service 索引快照

快照是叢集的索引和狀態的備份。狀態包含叢集設定、節點資訊、索引設定和碎片分配。

在 Amazon Elasticsearch Service 上,快照有兩種形式:自動和手動。

  • 自動快照僅適用叢集復原。在發生紅色叢集狀態或其他資料遺失時,您可以使用它們來還原您的網域。Amazon ES 會將自動快照存放在預先設定的 Amazon S3 儲存貯體中,並且不收取其他費用。

  • 手動快照適用於叢集復原,將資料從一個叢集移至另一個叢集。顧名思義,您必須初始化手動快照。這些快照會存放在您自己的 Amazon S3 儲存貯體中,而且需支付標準 S3 費用。如果您擁有自我管理叢集的 Elasticsearch 快照,您甚至可以使用該快照遷移至 Amazon ES 網域。

所有 Amazon ES 網域都會建立自動快照,但頻率不同:

  • 網域若執行 5.3 版和更高版本的 Elasticsearch,Amazon ES 會每隔 1 小時自動拍攝快照,且最多可保留其中 336 個快照 (連續保留 14 天)。

  • 網域若執行 5.1 版和舊版的 Elasticsearch,Amazon ES 會每隔 1 天自動拍攝快照 (在您指定期間),且最多可保留其中 14 個快照 (連續保留 30 天)。

如果您的叢集進入紅色狀態,Amazon ES 會停止取得自動快照。如果您未在兩週內修正該問題,則可能會永久遺失您的叢集資料。如需故障診斷步驟,請參閱紅色叢集狀態

提示

許多使用者尋找像 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 函數的詳細資訊,請參閱在 Amazon Elasticsearch Service 中使用 Curator 輪換資料

手動快照先決條件

若要手動建立索引快照,您必須使用 IAM 和 Amazon S3。嘗試拍攝快照之前,請先確認您已符合以下先決條件。

必要條件 描述
S3 儲存貯體

手動儲存 Amazon ES 網域的快照。請記下儲存貯體的名稱。對您而言它有兩個功用:

  • 附加至您 IAM 角色的 IAM 政策其 Resource 陳述式

  • 用於註冊快照儲存庫的 Python 用戶端

如需詳細資訊,請參閱《Amazon Simple Storage Service Getting Started Guide》中的建立儲存貯體

重要

請勿將 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 User Guide 中的新增和移除 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。用戶端需要 AWS SDK for Python (Boto 3) 請求 requests-aws4auth 套件。用戶端包含其他快照操作的註解範例。

提示

以 Java 為基礎的程式碼範例,請參閱簽署 HTTP 請求

您必須更新以下在您的程式碼中的變數: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 用戶端中的註解範例,對於 Curl 命令使用的相同端點提出已簽署 HTTP 請求。

手動拍攝快照

  1. 如果快照正在進行中,您就無法取得快照。若要檢查,請執行下列命令:

    curl -XGET 'elasticsearch-domain-endpoint/_snapshot/_status'
  2. 執行以下命令來手動拍攝快照:

    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'

    如果您不打算還原所有的索引,您可能只想要刪除一個索引:

    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'

    或者,您可能想要恢復所有索引 (.kibana 索引除外):

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

注意

如果不是所有涉及的索引都有主要碎片,快照可能一個 statePARTIAL。這個值表示至少一個碎片的資料未成功儲存。您仍然可以從部分快照還原,但您可能需要使用舊版的快照來還原任何遺失的索引。