备份你的集群edit

无论使用哪个存储数据的软件,定期备份数据都是很重要的。 Elasticsearch 副本在运行时提供了高可用性;它们让你可以容忍零星的节点丢失而不会中断服务。

但是,副本并不能提供对灾难性故障的保护。 为此,你需要的是对集群真正的备份 —— 一个完整的副本,以防出现问题。

要备份你的集群,你可以使用 snapshot API。 它会取得集群的当前状态和数据然后保存到一个共享仓库里。 这个备份过程是"智能"的。 第一个快照是数据的一个完整拷贝,但所有后续的快照都保存现有快照和新数据之间的增量。 随着你不时的对数据进行快照,备份数据也在增量的添加和删除。 这意味着后续备份会大大加快,因为它们传输的数据量少得多。

要使用这个功能,必须首先创建一个保存数据的仓库。有多个仓库类型可以供你选择:

  • 共享文件系统,比如 NAS
  • Amazon S3
  • HDFS (Hadoop 分布式文件系统)
  • Azure Cloud

创建仓库edit

让我们创建一个共享文件系统仓库:

PUT _snapshot/my_backup 
{
    "type": "fs", 
    "settings": {
        "location": "/mount/backups/my_backup" 
    }
}

给我们的仓库取一个名字,在本例中它叫my_backup

我们指定仓库的类型应该是一个共享文件系统(fs)。

最后,我们提供一个已挂载的设备作为目的地址。

必须确保集群种的所有节点都可以访问到这个共享文件系统路径。

这将在挂载点创建仓库和所需的元数据。 还有一些其他的选项你可能想要配置的,这些取决于你的节点、网络和仓库位置:

max_snapshot_bytes_per_sec
当快照数据进入仓库时,这个参数控制这个过程的限流。默认是每秒20mb
max_restore_bytes_per_sec
当从仓库恢复数据时,这个参数控制恢复时限流多少,以确保网络不会被占满。默认是每秒20mb

假设我们有一个非常快的网络,而且对额外的流量也很 OK,那我们可以增加这些默认值:

POST _snapshot/my_backup/ 
{
    "type": "fs",
    "settings": {
        "location": "/mount/backups/my_backup",
        "max_snapshot_bytes_per_sec" : "50mb", 
        "max_restore_bytes_per_sec" : "50mb"
    }
}

注意我们用的是 POST 而不是 PUT 。这会更新已有仓库的设置。

然后添加新的设置。

快照所有打开的索引 (Snapshotting All Open Indices)edit

一个仓库可以包含多个快照。每个快照跟一系列索引相关(比如所有索引,一部分索引,或者单个索引)。当创建快照的时候,你指定你感兴趣的索引然后给快照取一个唯一的名字。

让我们从最基础的快照命令开始:

PUT _snapshot/my_backup/snapshot_1

这个会备份所有打开的索引到 my_backup 仓库下一个命名为 snapshot_1 的快照里。 这个调用会立刻返回,然后快照会在后台运行。

通常你会希望你的快照作为后台进程运行,不过有时候你会希望在你的脚本中一直等待到完成。 这可以通过添加一个 wait_for_completion 标记实现:

PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true

这会阻塞调用直到快照完成。注意大型快照会花很长时间才返回。

快照指定索引 (Snapshotting Particular Indices)edit

默认行为是备份所有打开的索引。 不过如果你在用 Marvel,你不是真的想要把所有诊断相关的 .marvel 索引也备份起来。 可能你就压根没那么大空间备份所有数据。

这种情况下,可以在快照集群的时候指定备份哪些索引:

PUT _snapshot/my_backup/snapshot_2
{
    "indices": "index_1,index_2"
}

这个快照命令只会备份index1index2了。

列出快照相关的信息edit

一旦你开始在你的仓库里积攒起快照了,你可能会忘记里面各自的细节了 —— 特别是当快照是按照时间划分命名的时候(比如,backup_2014_10_28)。

要获得单个快照的信息,直接对仓库和快照名发起一个GET请求:

GET _snapshot/my_backup/snapshot_2

这将返回一个包括快照的各种信息的小的响应:

{
   "snapshots": [
      {
         "snapshot": "snapshot_1",
         "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

删除快照edit

最后,我们需要一个命令来删除所有不再有用的旧快照。 只要对仓库/快照名称发一个简单的DELETE HTTP 调用:

DELETE _snapshot/my_backup/snapshot_2

用 API 删除快照很重要,而不能用其他机制(比如手动删除,或者用 S3 上的自动清除工具)。 因为快照是增量的,有可能很多快照依赖于旧的段。delete API 知道哪些数据还在被最近的快照使用,只删除不再被使用的段。

但是,如果你手动删除文件,你将会面临备份严重损坏的风险,因为你正在删除仍在使用中的数据。

监控快照进度edit

wait_for_completion 标记提供了一种基础的监控形式,但哪怕只是对一个中等规模的集群做快照或恢复的时候,它都真的不够用。

另外两个 API 会给你有关快照状态更详细的信息。 首先你可以给快照 ID 执行一个 GET,就像我们之前获取一个特定快照的信息时做的那样:

GET _snapshot/my_backup/snapshot_3

如果你调用这个命令的时候快照还在进行中,你会看到它什么时候开始,运行了多久等等信息。 不过要注意,这个 API 用的是与快照机制相同的线程池。 如果你在快照非常大的分片,状态更新的间隔会很大,因为 API 在竞争相同的线程池资源。

更好的方案是轮循 _status API:

GET _snapshot/my_backup/snapshot_3/_status

_status API 立刻返回,并给出详细得多的统计输出:

{
   "snapshots": [
      {
         "snapshot": "snapshot_3",
         "repository": "my_backup",
         "state": "IN_PROGRESS", 
         "shards_stats": {
            "initializing": 0,
            "started": 1, 
            "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
                     }
                  },
                  ...

一个正在运行的快照会显示IN_PROGRESS状态。

这个特定的快照还有一个分片在传输(另外四个已经完成)。

响应包括快照的总体状况,但也深入到每个索引和每个分片的统计。 这为你提供了有关快照进展的非常详细的视图。 分片可以处于不同的完成状态:

INITIALIZING
分片正在检查集群状态,看看自己是否可以被快照。这个通常很快。
STARTED
数据正在被传输到仓库。
FINALIZING
数据传输完成;分片现在在发送快照元数据。
DONE
快照完成!
FAILED
快照处理的过程中遇到了错误,这个分片/索引/快照不可能完成了。 检查你的日志以获取更多信息。

取消一个快照edit

最后,你可能想取消一个快照或恢复。 因为这些是长期运行的进程,执行操作的时候一个拼写错误或者失误就需要花很长时间去解决 —— 同时还会耗尽宝贵的资源。

要取消一个快照,只需在快照正在进行时删除它:

DELETE _snapshot/my_backup/snapshot_3

这个会中断快照进程。然后从仓库里删除进行了一半的快照。