快照及恢复
更新时间:2018-07-31 17:47:13
要备份您的阿里云Elasticsearch集群,您可以使用 snapshot
API。该API会拿到您的集群当前的状态和数据,然后保存到一个共享仓库里。这个备份过程是”智能”的。
您的第一个快照会是一个数据的完整拷贝,但所有后续的快照保留的是已存快照和新数据之间的差异。随着您不时的对数据进行快照,备份也在增量的添加和删除。这意味着后续备份会相当快速,因为它们只传输很小的数据量。
温馨提示
如何使用快照方式,完成自建Elasticsearch迁移至阿里云Elasticsearch,详情请参见 OSS快照迁移Elasticsearch。
注意
本文代码中的 <1>、<2>、<3> 这3个标记,用于标识位置,方便对指定位置代码描述。实际执行对应代码时,需去掉有包含这3个类型的标记。
创建仓库
- 建议使用标准存储类型OSS数据源(不支持归档存储类型OSS)。
- <1> 此处的OSS,必须和您的阿里云ES集群在同一个region中,下面的
endpoint
填的是这个 region 对应的内网地址 。详情请参见 访问域名和数据中心 中ECS访问的内网Endpoint
一栏。 - <2> 需要一个已经存在的OSS bucket。
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
}
}
限制分块大小
假设我们上传的数据非常大, 我们可以限制snapshot过程中分块的大小,超过这个大小,数据将会被分块上传到OSS中。
- <1> 注意用的是
POST
而不是PUT
,这会更新已有仓库的设置。 - <2> base_path 设置仓库的起始位置,默认为根目录。
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>
}
}
列出仓库信息
GET _snapshot
- 也可以使用
GET _snapshot/my_backup
获取指定仓库的信息。
备份快照迁移
如果需要将快照迁移到另一个集群,只需要备份到OSS。然后再在新的集群上注册一个快照仓库(相同的OSS),设置base_path
的位置为备份文件所在的地方,然后执行恢复备份的命令即可。
快照所有打开的索引
一个仓库可以包含多个快照,每个快照跟一系列索引相关(比如所有索引,一部分索引,或者单个索引)。当创建快照的时候,指定您感兴趣的索引,然后给快照取一个唯一的名字。
快照命令
-
让我们从最基础的快照命令开始:
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"
}
这个快照命令,现在只会备份 index1
和 index2
。
列出快照信息
有时您可能会忘记仓库里的快照细节,特别是快照按时间划分命名的时候(比如 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
删除快照
可对仓库/快照名称,发一个DELETE
命令的 HTTP 调用,来删除所有不再有用的旧快照:
DELETE _snapshot/my_backup/snapshot_2
使用 API 来删除快照很重要,而不能使用其他机制(比如手动删除)。因为快照是增量的,有可能很多快照依赖于过去的段。delete
API 知道哪些数据还在被更多近期快照使用,然后会只删除不再被使用的段。
注意
如果您做了一次人工文件删除,您将会面临备份严重损坏的风险,因为您删除的可能是还在使用中的数据。
监控快照进度
该wait_for_completion
标记,提供了基础监控形式。如果您需要对中等规模的集群做快照恢复时,可能会不够用。以下2个 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", <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> 这个特定快照有一个分片还在传输(另外四个已经完成)。
响应包括快照的总体状况,但也包括下钻到每个索引和每个分片的统计值。这个给您展示了有关快照进展的非常详细的视图。分片可以在不同的完成状态:
INITIALIZING
:分片在检查集群状态看看自己是否可以被快照。这个一般是非常快的。STARTED
:数据正在被传输到仓库。FINALIZING
:数据传输完成;分片现在在发送快照元数据。DONE
:快照完成!FAILED
:快照处理的时候碰到了错误,这个分片/索引/快照不可能完成了。检查您的日志获取更多信息。
取消快照
如果您想取消一个快照,可以在任务进行中的时候,执行以下删除快照命令:
DELETE _snapshot/my_backup/snapshot_3
这个会中断快照进程。然后删除仓库里进行到一半的快照。
从快照恢复
-
如果您已备份过数据,执行恢复操作相对比较简单,只要在您希望恢复回集群的快照 ID 后面加上
_restore
即可:POST _snapshot/my_backup/snapshot_1/_restore
默认行为是把这个快照里存有的所有索引都恢复。如果
snapshot_1
包括五个索引,这五个都会被恢复到我们集群里。和snapshot
API 一样,我们也可以选择希望恢复具体哪个索引。 -
还有附加的选项用来重命名索引。这个选项允许您通过模式匹配索引名称,然后通过恢复进程提供一个新名称。如果您想在不替换现有数据的前提下,恢复老数据来验证内容,或者做其他处理,这个选项很有用。让我们从快照里恢复单个索引并提供一个替换的名称:
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> 然后把它们重命名成替代的模式。
-
和快照类似,
restore
命令也会立刻返回,恢复进程会在后台进行。如果您更希望您的 HTTP 调用阻塞直到恢复完成,添加wait_for_completion
标记:POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true
监控恢复操作
从仓库恢复数据借鉴了 Elasticsearch 里已有的现行恢复机制。在内部实现上,从仓库恢复分片和从另一个节点恢复是等价的。
如果您想监控恢复的进度,您可以使用 recovery
API。这是一个通用目的的 API,用来展示您集群中移动着的分片状态。
-
这个 API 可以为您在恢复的指定索引单独调用:
GET restored_index_3/_recovery
-
或者查看您集群里所有索引,可能包括跟您的恢复进程无关的其他分片移动:
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.1.7",
"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
字段告诉您恢复的本质;这个分片是在从一个快照恢复。 - <2>
source
哈希描述了作为恢复来源的特定快照和仓库。 - <3>
percent
字段让您对恢复的状态有个概念。这个特定分片目前已经恢复了 94% 的文件,它就快完成了。
输出会列出所有目前正在经历恢复的索引,然后列出这些索引里的所有分片。每个分片里会有启动/停止时间、持续时间、恢复百分比、传输字节数等统计值。
取消恢复
您可以通过删除正在恢复的索引,取消一个恢复。因为恢复进程其实就是分片恢复,发送一个 删除索引
API 修改集群状态,就可以停止恢复进程。比如:
DELETE /restored_index_3
如果 restored_index_3
正在恢复中,这个删除命令会停止恢复,同时删除所有已经恢复到集群里的数据。