通过快照备份及恢复命令(snapshot API),您可以备份并恢复阿里云Elasticsearch(简称ES)实例中的数据。snapshot API会获取实例当前的状态和数据,然后保存到一个共享仓库里。

注意事项

  • 快照仅保存索引数据,不保存阿里云ES实例自身的监控数据(例如以.monitoring和.security_audit为前缀的索引)、元数据、Translog、配置、阿里云ES的软件包、自带和自定义的插件、阿里云ES的日志等。
  • 本文代码中的<1>、<2>、<3>这三个标记用于标识位置,方便对指定位置代码描述。实际执行对应代码时,需去掉有包含这三个类型的标记。
  • 本文中的代码均可以在阿里云ES实例的Kibana控制台上执行,详情请参见登录Kibana控制台
  • 本文中部分内容参考了开源elasticsearch-repository-oss文档。

前提条件

已开通阿里云对象存储服务OSS(Object Storage Service),并新建了一个OSS Bucket。
注意 请创建标准存储类型的OSS Bucket(不支持归档存储类型),且OSS Bucket的区域必须与阿里云ES实例所在区域保持一致。

具体操作步骤请参见开通OSS服务创建存储空间

创建仓库

PUT _snapshot/my_backup
{
   "type": "oss",
    "settings": {
        "endpoint": "http://oss-cn-hangzhou-internal.aliyuncs.com", <1>
        "access_key_id": "xxxx",
        "secret_access_key": "xxxxxx",
        "bucket": "xxxxxx", <2>
        "compress": true,
        "base_path": "snapshot/" <3>
    }
}
说明 获取access_key_idsecret_access_key的方式请参见如何获取AccessKeyId和AccessKeySecret
  • <1>:endpoint为OSS Bucket对应的内网地址,详情请参见访问域名和数据中心
  • <2>:OSS Bucket的名称,需要一个已经存在的OSS Bucket。Bucket名称的获取方式请参见创建存储空间
  • <3>:设置仓库的起始位置,默认为根目录。

限制分块大小

当您上传的数据非常大时,可以通过配置chunk_size参数限制快照过程中分块的大小,超过这个大小,数据将会被分块上传到OSS中。

POST _snapshot/my_backup/ <1>
{
    "type": "oss",
    "settings": {
        "endpoint": "http://oss-cn-hangzhou-internal.aliyuncs.com",
        "access_key_id": "xxxx",
        "secret_access_key": "xxxxxx",
        "bucket": "xxxxxx",
        "chunk_size": "500mb",
        "base_path": "snapshot/" <2>
    }
}
  • <1>:请求方式,注意使用POST而不是PUT,这会更新已有仓库的设置。
  • <2>:设置仓库的起始位置,默认为根目录。

列出仓库信息

GET _snapshot

您也可以使用GET _snapshot/my_backup获取指定仓库的信息。

创建快照

最基础的创建快照的命令如下。
PUT _snapshot/my_backup/snapshot_1

以上命令会备份所有打开的索引到my_backup仓库下,并保存在名称为snapshot_1的快照中。这个命令会立刻返回,然后备份会在后台运行。

如果您希望在脚本中一直等待到完成,可通过添加wait_for_completion实现。
PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true

以上命令会阻塞调用直到备份完成。如果是大型快照,需要很长时间才能返回。

说明 第一次进行快照时,系统会备份您所有的数据,后续所有的快照仅备份已存快照和新快照之间的增量数据。随着数据快照的不断进行,备份也在增量的添加和删除。这意味着后续备份会相当快速,因为它们只传输很小的数据量。

快照指定索引

系统默认会备份所有打开的索引。如果您在使用Kibana,并且考虑到磁盘空间大小因素,不需要把所有诊断相关的.kibana索引都备份起来,那么可以在进行集群备份时,指定需要快照的索引。
注意 一个仓库可以包含多个快照,每个快照跟一系列索引相关(例如所有索引,一部分索引,或者单个索引)。当创建快照的时候,您可以指定感兴趣的索引,然后给快照取一个唯一的名字。
PUT _snapshot/my_backup/snapshot_2
{
    "indices": "index_1,index_2"
}

以上命令只会备份名称为index1index2的索引。

列出快照信息

有时您可能会忘记仓库里的快照细节,特别是快照按时间划分命名的时候(例如backup_2014_10_28)。

当您需要查看仓库中的某个快照时,可对仓库和快照名发起一个GET请求,获取单个快照信息。
GET _snapshot/my_backup/snapshot_2

返回结果中包括了快照相关的各种信息,如下所示。

{
"snapshots": [
   {
      "snapshot": "snapshot_2",
      "indices": [
         ".marvel_2014_28_10",
         "index1",
         "index2"
      ],
      "state": "SUCCESS",
      "start_time": "2014-09-02T13:01:43.115Z",
      "start_time_in_millis": 1409662903115,
      "end_time": "2014-09-02T13:01:43.439Z",
      "end_time_in_millis": 1409662903439,
      "duration_in_millis": 324,
      "failures": [],
      "shards": {
         "total": 10,
         "failed": 0,
         "successful": 10
      }
   }
]
}

您也可以使用_all替换掉具体的快照名称,获取一个仓库中所有快照的完整列表。

GET _snapshot/my_backup/_all

监控快照进度

您可以使用wait_for_completion,对快照进行监控,但其仅提供了基础的监控形式。如果您需要对中等规模的集群进行快照监控,可能会不够用,此时可以通过以下两种方式获取详细的快照进度信息:

  • 给快照名发送一个GET请求。
    GET _snapshot/my_backup/snapshot_3

    如果在执行这个命令时,快照还在进行中,那么可以看到它什么时候开始,运行了多久等信息。

    注意 这个API用的是与快照机制相同的线程池,当您在对非常大的分片进行快照时,状态更新的间隔会很大,因为API在竞争相同的线程池资源。
  • 使用_status API获取快照的状态信息。
    {
    "snapshots": [
       {
          "snapshot": "snapshot_3",
          "repository": "my_backup",
          "state": "IN_PROGRESS", <1>
          "shards_stats": {
             "initializing": 0,
             "started": 1, <2>
             "finalizing": 0,
             "done": 4,
             "failed": 0,
             "total": 5
          },
          "stats": {
             "number_of_files": 5,
             "processed_files": 5,
             "total_size_in_bytes": 1792,
             "processed_size_in_bytes": 1792,
             "start_time_in_millis": 1409663054859,
             "time_in_millis": 64
          },
          "indices": {
             "index_3": {
                "shards_stats": {
                   "initializing": 0,
                   "started": 0,
                   "finalizing": 0,
                   "done": 5,
                   "failed": 0,
                   "total": 5
                },
                "stats": {
                   "number_of_files": 5,
                   "processed_files": 5,
                   "total_size_in_bytes": 1792,
                   "processed_size_in_bytes": 1792,
                   "start_time_in_millis": 1409663054859,
                   "time_in_millis": 64
                },
                "shards": {
                   "0": {
                      "stage": "DONE",
                      "stats": {
                         "number_of_files": 1,
                         "processed_files": 1,
                         "total_size_in_bytes": 514,
                         "processed_size_in_bytes": 514,
                         "start_time_in_millis": 1409663054862,
                         "time_in_millis": 22
                      }
                   },
                   ...
    • <1>:快照的状态。一个正在运行的快照,会显示为IN_PROGRESS
    • <2>:正在快照传输的分片数量。为1时,表示这个特定快照有一个分片还在传输(另外四个已经完成)。
      shards_stats响应不仅包括快照的总体状况,也包括下钻到每个索引和每个分片的统计值。此参数展示了快照进度的详细信息。分片可以在不同的完成状态:
      • INITIALIZING:分片在检查集群状态,查看是否可以被快照。此过程一般是非常快的。
      • STARTED:数据正在被传输到仓库。
      • FINALIZING:数据传输完成,分片正在发送快照元数据。
      • DONE:快照完成。
      • FAILED:快照过程中碰到了错误,这个分片/索引/快照不可能完成。可查看日志获取更多信息。

备份快照迁移

按照以下步骤将当前快照迁移到另外一个集群:

  1. 将当前快照备份到OSS。
  2. 在新集群上创建一个快照仓库(相同的OSS)。
  3. 将新集群的快照仓库的base_path设置为第一步中快照备份的路径。
  4. 在新集群中执行快照恢复命令。
    说明 以上步骤为一个简单的备份快照迁移解决方案,详细步骤请参见OSS快照迁移Elasticsearch

取消快照

如果您想取消一个快照,可以在任务进行中的时候,执行以下命令删除快照。

DELETE _snapshot/my_backup/snapshot_3

以上命令会中断快照进程并删除仓库中进行到一半的快照。

恢复快照

注意 恢复.开头的系统索引可能会导致Kibana访问失败,建议不要恢复系统索引数据。

在需要恢复索引的目标阿里云ES实例上,再执行和之前相同的创建仓库命令。您可以根据实际情况,通过以下两种方式进行快照恢复:

  • 如果您已备份过数据,可直接在需要恢复的快照名后面加上_restore
    POST _snapshot/my_backup/snapshot_1/_restore

    系统默认会恢复指定快照中的所有索引。例如snapshot_1包括五个索引,那么这五个索引都会被恢复到集群中。

    和快照类似,_restore API会立刻返回,恢复进程会在后台进行。如果您更希望HTTP调用阻塞直到恢复完成,可以参考以下命令添加wait_for_completion
    POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true
  • 如果您需要在不替换现有数据的前提下,恢复旧版本的数据来验证内容,或者进行其他处理,可恢复指定的索引,并对恢复的索引进行重命名。
    POST /_snapshot/my_backup/snapshot_1/_restore
    {
     "indices": "index_1", <1>
     "rename_pattern": "index_(.+)", <2>
     "rename_replacement": "restored_index_$1" <3>
    }

    以上命令会恢复index_1到您集群里,并且重命名成了restored_index_1

    • <1>:只恢复index_1索引,忽略快照中的其他索引。
    • <2>:查找正在恢复的索引,该索引名称需要与提供的模板匹配。
    • <3>:重命名查找到的索引。

监控恢复操作

说明 从仓库恢复数据借鉴了Elasticsearch里已有的现行恢复机制。在内部实现上,从仓库恢复分片和从另一个节点恢复是等价的。
您可以通过recovery API来监控恢复的进度。
  • 监控指定索引的恢复状态。
    GET restored_index_3/_recovery

    recovery API是一个通用的API,可以用来展示集群中移动着的分片状态。

  • 查看集群中的所有索引的恢复信息(可能包含跟您的恢复进程无关的其他分片的恢复信息)。
    GET /_recovery/
    示例输出结果如下。
    {
    "restored_index_3" : {
     "shards" : [ {
       "id" : 0,
       "type" : "snapshot", <1>
       "stage" : "index",
       "primary" : true,
       "start_time" : "2014-02-24T12:15:59.716",
       "stop_time" : 0,
       "total_time_in_millis" : 175576,
       "source" : { <2>
         "repository" : "my_backup",
         "snapshot" : "snapshot_3",
         "index" : "restored_index_3"
       },
       "target" : {
         "id" : "ryqJ5lO5S4-lSFbGntkEkg",
         "hostname" : "my.fqdn",
         "ip" : "10.0.**.**",
         "name" : "my_es_node"
       },
       "index" : {
         "files" : {
           "total" : 73,
           "reused" : 0,
           "recovered" : 69,
           "percent" : "94.5%" <3>
         },
         "bytes" : {
           "total" : 79063092,
           "reused" : 0,
           "recovered" : 68891939,
           "percent" : "87.1%"
         },
         "total_time_in_millis" : 0
       },
       "translog" : {
         "recovered" : 0,
         "total_time_in_millis" : 0
       },
       "start" : {
         "check_index_time" : 0,
         "total_time_in_millis" : 0
       }
     } ]
    }
    }
    • <1>:type字段定义了您恢复的类型。snapshot表示这个分片是在从一个快照恢复的。
    • <2>:source字段定义了作为恢复来源的特定快照和仓库。
    • <3>:percent字段定义了恢复的状态。94.5%表示这个特定分片目前已经恢复了94.5%的文件。

    输出结果会展示所有正在恢复中的索引,并列出这些索引里的所有分片。同时每个分片中会显示启动和停止时间、持续时间、恢复百分比、传输字节数等统计值。

取消恢复

您可以通过删除正在恢复的索引,取消一个恢复操作(因为恢复进程其实就是分片恢复,发送一个DELETE API请求修改集群状态,就可以停止恢复进程)。
DELETE /restored_index_3

如果restored_index_3正在恢复中,以上删除命令会停止恢复,同时删除所有已经恢复到集群中的数据,详情请参见Snapshot And Restore

删除快照

您可以对仓库和快照发起一个DELETE请求,删除所有不再使用的快照。

DELETE _snapshot/my_backup/snapshot_2
注意
  • 请使用delete API来删除快照,而不能使用其他机制(例如手动删除)。因为快照是增量的,很多快照可能依赖于之前的备份数据。delete API能够过滤出还在被其他快照使用的数据,只删除不再被使用的备份数据。
  • 如果您进行了一次人工文件删除,您将会面临备份严重损坏的风险,因为您删除的文件可能还在使用中。