前面的背景参见:elasticsearch备份与恢复1_安装Hadoop HDFS
备份es数据,要使用snapshot api。这个api会将es当前的状态和数据全部存储到一个外部的共享目录中去,如HDFS。
恢复索引数据,使用restore api,会将保存在HDFS中的索引snapshot恢复到es中
官方snapshot及restore文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.3/modules-snapshots.html
安装repository-hdfs插件
先停掉es,之后安装repository-hdfs的插件
官方参考文档:https://www.elastic.co/guide/en/elasticsearch/plugins/6.3/repository-hdfs.html
bin/elasticsearch-plugin install repository-hdfs
重新启动的时候,可以看到es日志中
[2018-08-09T14:08:34,777][INFO ][o.e.p.PluginsService ] [rS8YfY_] loaded plugin [repository-hdfs]
repository-hdfs plugin是与hadoop整合起来使用的。所以如果我们使用的hadoop版本跟这个es repository-hdfs plugin的版本不兼容,那么考虑在hdfs plugin的文件夹里,将hadoop相关jar包都替换成我们自己的hadoop版本对应的jar包。
安装好了hdfs plugin之后,就可以创建hdfs仓库了
一定记得打开docker02防火墙50010端口,否则就会报错
There are 1 datanode(s) running and 1 node(s) are excluded in this operation.
创建HDFS仓库
一定记得打开docker02防火墙9000端口,否则就会报错
kibana语句为
PUT _snapshot/my_hdfs_repository
{
"type": "hdfs",
"settings": {
"uri": "hdfs://192.168.211.104:9000/",
"path": "/usr/local/data/my_hdfs_repository",
"conf.dfs.client.read.shortcircuit": "false"
}
}
这样就会在docker02的/usr/local/data/my_hdfs_repository下创建hdfs仓库
创建完仓库后,可以通过curl语句来验证仓库状态
curl -XPOST 'http://192.168.211.108:9200/_snapshot/my_hdfs_repository/_verify'
对索引进行snapshot备份
1. 对所有open的索引进行备份
一个仓库可以包含多份snapshot,每个snapshot是一部分索引的备份数据,创建一份snapshot备份时,我们要指定要备份的索引。
比如下面这行命令:
PUT _snapshot/my_hdfs_repository/snapshot_1,这行命令就会将所有open的索引都放入一个叫做snapshot_1的备份,并且放入my_hdfs_repository仓库中。这个命令会立即返回,然后备份操作会被后台继续进行。
如果我们不希望备份操作以后台方式运行,而是希望在前台发送请求时等待备份操作执行完成,那么可以加一个参数即可。
比如这样:PUT _snapshot/my_hdfs_repository/snapshot_1?wait_for_completion=true
2. 对指定的索引进行备份
kibana语句
PUT _snapshot/my_hdfs_repository/snapshot_2
{
"indices": "index_1",
"ignore_unavailable": true,
"include_global_state": false,
"partial": true
}
ignore_unavailable如果设置为true的话,那么那些不存在的index就会被忽略掉。默认情况下,这个参数是不设置的,那么此时如果某个index丢失了,会导致备份过程失败。
设置include_global_state为false,可以阻止cluster的全局state也作为snapshot的一部分被备份。
默认情况下,如果某个索引的部分primary shard不可用,那么会导致备份过程失败,那么此时可以将partial设置为true。
一般来说,备份是在一个shell脚本里,你用crontab做一个定时,比如每天凌晨1点,就将所有的数据做一次增量备份,当然,如果你的数据量较大,每小时做一次也ok。shell脚本里,就用curl命令,自动发送一个snapshot全量数据的请求。那么这样的话,就会自动不断的去做增量备份
备份完成之后,通过Browser HDFS可以看到
增量备份
snapshot的过程是增量进行的,每次执行snapshot的时候,es会分析已经存在于仓库中的snapshot对应的index file,然后仅仅备份那些自从上次snapshot之后新创建的或者有过修改的index files。这就允许多个snapshot在仓库中可以用一种紧凑的模式来存储。而且snapshot过程是不会阻塞所有的es读写操作的,然而,在snapshot开始之后,写入index中的数据,是不会反映到这次snapshot中的。每次snapshot除了创建一份index的副本之外,还可以保存全局的cluster元数据,里面包含了全局的cluster设置和template。
查看snapshot备份列表
GET _snapshot/my_hdfs_repository/snapshot_1?pretty
删除备份
如果要删除过于陈旧的snapshot备份快照,那么使用下面这行命令即可:
DELETE _snapshot/my_snapshot_repository/snapshot_2。
记住,一定要用api去删除snapshot,不要自己手动在hdfs里删除这个数据。因为snapshot是增量的,有可能很多snapshot依赖于底层的某一个公共的旧的snapshot segment。但是delete api是理解数据如何增量存储和互相依赖的,所以可以正确的删除那些不用的数据。如果我们自己手工进行hdfs文件删除,可能导致我们的backup数据破损掉,就无法使用了
监控snapshot的进度
GET _snapshot/my_snapshot_repository/snapshot_3/_status
这个api立即返回最详细的数据。这里我们可以看到总共有几个shard在备份,已经完成了几个,还剩下几个,包括每个索引的shard的备份进度
取消snapshot备份过程
如果我们想要取消一个正在执行的snapshot备份过程,比如我们发现备份时间过于长,希望先取消然后在晚上再运行,或者是因为不小心误操作发起了一次备份操作,这个时候就可以运行下面这条命令:
DELETE _snapshot/my_snapshot_repository/snapshot_3。
也就是立即删除这个snapshot,这个命令会去取消snapshot的过程,同时将备份了一半的仓库中的数据给删除掉。
数据恢复
3. 基于snapshot数据恢复
restore过程只能针对已经close掉的index来执行,而且这个index的shard还必须跟snapshot中的index的shard数量是一致的。restore操作会自动在恢复好一个index之后open这个index,或者如果这些index不存在,那么就会自动创建这些index。如果通过include_global_state存储了集群的state,还会同时恢复一些template。
如果你要做数据恢复,比如说,你自己误删除,不小心将整个index给删除掉了,数据丢了,很简单,直接用最新的那个snapshot就可以了
POST /_snapshot/my_hdfs_repository/snapshot_1/_restore
{
"indices": "hzeg-history-words",
"ignore_unavailable": true,
"include_global_state": true
}
这个restore过程也是在后台运行的,如果要在前台等待它运行完,那么可以加上
?wait_for_completion flag,包括之前的备份过程,也是一样的,对运维中的自动化shell脚本,很重要,你的shell脚本里,要比如等待它备份完成了以后,才会去执行下一条命令
监控restore的进度
从一个仓库中恢复数据,其实内部机制跟从其他的node上恢复一个shard是一样的。如果要监控这个恢复的过程,可以用recovery api,比如:
GET restored_index/_recovery。
如果要看所有索引的恢复进度:GET /_recovery/。可以看到恢复进度的大致的百分比。
取消恢复过程
如果要取消一个恢复过程,那么需要删除已经被恢复到es中的数据。因为一个恢复过程就只是一个shard恢复,发送一个delete操作删除那个索引即可,比如:
DELETE /restored_index。如果那个索引正在被恢复,那么这个delete命令就会停止恢复过程,然后删除已经恢复的所有数据