一、安装nfs和rpcbind
1、服务端(192.168.1.3)
在一台数据备份的服务器上安装nfs和rpcbind,并启动:
[root@localhost ~]# yum -y install nfs-utils rpcbind
[root@localhost ~]# service rpcbind start
[root@localhost ~]# service nfs start
创建共享目录:
[root@localhost ~]# mkdir -p /data/es
[root@localhost ~]# chown -R elasticsearch:elasticsearch /data
配置exports文件并使其立即生效:
[root@localhost ~]# vim /etc/exports
/data/es *(rw)
[root@localhost ~]# exportfs -a
2、客户端
创建共享目录,所有的ES节点都要创建:
[root@localhost ~]# mkdir -p /data/es_backup/
[root@localhost ~]# chown -R elasticsearch:elasticsearch /dataes_backup/
3、尝试挂载:
在任意ES节点执行远程挂载命令:
[root@localhost ~]# mount -t nfs 192.168.1.3:/data/es /data/es_backup/
没有报错的话,就挂载成功了。
二、创建ES备份仓库
1、修改ES配置,在所有的ES节点的配置文件中加入一行配置,并重启所有节点:
[root@localhost ~]# vim /etc/elasticsearch/elasticsearch.yml
......
path.repo: ["/data/es_backup"]
......
2、在Kibana的“开发工具”执行以下命令:
PUT /_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/data/es_backup"
}
}
查看返回结果:
{
"acknowledged" : true
}
如有报错的话,检查一下各节点的文件目录权限问题。
三、建立快照
查看当前存在的索引:
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open .kibana_task_manager_1 XJL-tjI9SpCA_fe79A05vg 1 1 2 1 107.2kb 60.4kb
green open .apm-agent-configuration kGo27hTHQyKCPPbtfHzpeg 1 1 0 0 566b 283b
green open .kibana_1 fLrmHniMTy-LT_Z3Mc6Vdw 1 1 10 0 59kb 29.5kb
1、创建快照:
PUT /_snapshot/my_backup/snapshot_1
这个会备份所有打开的索引到 my_backup 仓库下一个命名为 snapshot_1 的快照里。这个调用会立刻返回,然后快照会在后台运行。
在任意ES节点查看/data/es_backup下生成的文件:
[root@localhost ~]# cd /data/es_backup/
[root@localhost es_backup]# ll
总用量 40
-rw-r--r--. 1 elasticsearch elasticsearch 549 3月 25 18:13 index-0
-rw-r--r--. 1 elasticsearch elasticsearch 8 3月 25 18:13 index.latest
drwxr-xr-x. 5 elasticsearch elasticsearch 96 3月 25 18:13 indices
-rw-r--r--. 1 elasticsearch elasticsearch 26422 3月 25 18:13 meta-3wy5okWmRhijqjL2TaJeVg.dat
-rw-r--r--. 1 elasticsearch elasticsearch 304 3月 25 18:13 snap-3wy5okWmRhijqjL2TaJeVg.dat
drwxr-xr-x. 2 elasticsearch elasticsearch 123 3月 25 15:06 tests-2e3dxJMVTUSdVccmNw72EA
通常我们会希望快照作为后台进程运行,不过有时候会希望一直等待到完成。这可以通过添加一个 wait_for_completion 标记实现:
PUT /_snapshot/my_backup/snapshot_1?wait_for_completion=true
2、创建指定索引的快照:
快照的默认行为是备份所有打开的索引。不过如果你在生产中,不可能把所有的索引都备份起来,可能你就压根没那么大空间备份所有数据。
这种情况下,你可以在快照你的集群的时候指定备份哪些索引:
PUT /_snapshot/my_backup/snapshot_2
{
"indices": ".kibana_1"
}
这个快照命令现在只会备份.kibana_1 了。
3、列出快照的信息,只需要把PUT改为GET:
GET /_snapshot/my_backup/snapshot_1
查看结果:
{
"snapshots" : [
{
"snapshot" : "snapshot_1",
"uuid" : "3wy5okWmRhijqjL2TaJeVg",
"version_id" : 7060099,
"version" : "7.6.0",
"indices" : [
".kibana_1",
".kibana_task_manager_1",
".apm-agent-configuration"
],
"include_global_state" : true,
"state" : "SUCCESS",
"start_time" : "2020-03-25T10:13:27.097Z",
"start_time_in_millis" : 1585131207097,
"end_time" : "2020-03-25T10:13:28.914Z",
"end_time_in_millis" : 1585131208914,
"duration_in_millis" : 1817,
"failures" : [ ],
"shards" : {
"total" : 3,
"failed" : 0,
"successful" : 3
}
}
]
}
要获取一个仓库中所有快照的完整列表,使用 _all 占位符替换掉具体的快照名称:
{
"snapshots" : [
{
"snapshot" : "snapshot_1",
"uuid" : "3wy5okWmRhijqjL2TaJeVg",
"version_id" : 7060099,
"version" : "7.6.0",
"indices" : [
".kibana_1",
".kibana_task_manager_1",
".apm-agent-configuration"
],
"include_global_state" : true,
"state" : "SUCCESS",
"start_time" : "2020-03-25T10:13:27.097Z",
"start_time_in_millis" : 1585131207097,
"end_time" : "2020-03-25T10:13:28.914Z",
"end_time_in_millis" : 1585131208914,
"duration_in_millis" : 1817,
"failures" : [ ],
"shards" : {
"total" : 3,
"failed" : 0,
"successful" : 3
}
},
{
"snapshot" : "snapshot_2",
"uuid" : "X1SFYYQiQ1mxxYbcBSvs4w",
"version_id" : 7060099,
"version" : "7.6.0",
"indices" : [
".kibana_1"
],
"include_global_state" : true,
"state" : "SUCCESS",
"start_time" : "2020-03-25T10:28:09.413Z",
"start_time_in_millis" : 1585132089413,
"end_time" : "2020-03-25T10:28:09.613Z",
"end_time_in_millis" : 1585132089613,
"duration_in_millis" : 200,
"failures" : [ ],
"shards" : {
"total" : 1,
"failed" : 0,
"successful" : 1
}
}
]
}
四、删除快照
最后,我们需要一个命令来删除所有不再有用的旧快照:
DELETE /_snapshot/my_backup/snapshot_2
再查看一下当前的快照,只剩下snapshot_1了:
{
"snapshots" : [
{
"snapshot" : "snapshot_1",
"uuid" : "3wy5okWmRhijqjL2TaJeVg",
"version_id" : 7060099,
"version" : "7.6.0",
"indices" : [
".kibana_1",
".kibana_task_manager_1",
".apm-agent-configuration"
],
"include_global_state" : true,
"state" : "SUCCESS",
"start_time" : "2020-03-25T10:13:27.097Z",
"start_time_in_millis" : 1585131207097,
"end_time" : "2020-03-25T10:13:28.914Z",
"end_time_in_millis" : 1585131208914,
"duration_in_millis" : 1817,
"failures" : [ ],
"shards" : {
"total" : 3,
"failed" : 0,
"successful" : 3
}
}
]
}
五、监控快照进度
这段参考ES官网文档:
wait_for_completion 标记提供了一个监控的基础形式,但哪怕只是对一个中等规模的集群做快照恢复的时候,它都真的不够用。
另外两个 API 会给你有关快照状态更详细的信息。首先你可以给快照 ID 执行一个 GET,就像我们之前获取一个特定快照的信息时做的那样:
GET /_snapshot/my_backup/snapshot_1
如果你调用这个命令的时候快照还在进行中,你会看到它什么时候开始,运行了多久等等信息。不过要注意,这个 API 用的是快照机制相同的线程池。如果你在快照非常大的分片,状态更新的间隔会很大,因为 API 在竞争相同的线程池资源。
更好的方案是拽取 _status API 数据:
GET /_snapshot/my_backup/snapshot_1/_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
},
一个正在运行的快照会显示 IN_PROGRESS 作为状态。5个分片已经完成(done)4个,1个(started)还在传输。
响应包括快照的总体状况,但也包括下钻到每个索引和每个分片的统计值。这个给你展示了有关快照进展的非常详细的视图。分片可以在不同的完成状态:
INITIALIZING
分片在检查集群状态看看自己是否可以被快照。这个一般是非常快的。
STARTED
数据正在被传输到仓库。
FINALIZING
数据传输完成;分片现在在发送快照元数据。
DONE
快照完成!
FAILED
快照处理的时候碰到了错误,这个分片/索引/快照不可能完成了。检查你的日志获取更多信息。
取消正在进行的快照:
取消一个正在进行的快照,只需要执行DELETE即可:
DELETE /_snapshot/my_backup/snapshot_1
这个会中断快照进程。然后删除仓库里进行到一半的快照。
六、从快照恢复
我们先查看一下当前的索引:
GET /_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open nginx R27xDC05Ruelx16TVnvUkg 1 1 2406968 0 284.2mb 146.5mb
green open test Iq0Mr67uTS-_H6qK7q1reA 1 1 7 0 15.6kb 7.8kb
green open .kibana_task_manager_1 XJL-tjI9SpCA_fe79A05vg 1 1 2 1 43.8kb 17kb
green open .apm-agent-configuration kGo27hTHQyKCPPbtfHzpeg 1 1 0 0 566b 283b
green open .kibana_1 fLrmHniMTy-LT_Z3Mc6Vdw 1 1 33 15 123kb 65.2kb
green open nginx-2020.03.25 me_l1hL9Tg2i9yk_61ETnA 1 1 71530 0 12.1mb 6mb
然后针对test索引生成一个快照:
PUT /_snapshot/my_backup/test
{
"indices": "test"
}
删除test索引:
DELETE /test
现在使用快照恢复test:
POST /_snapshot/my_backup/test/_restore
如果我们一个快照里面有很多个索引的数据,只想恢复其中一个索引信息怎么处理呢?只需要指定索引名称就好了:
POST /_snapshot/my_backup/snapshot_1/_restore
{
#只恢复 test 索引,忽略快照中存在的其余索引。
"indices": "test",
#查找所提供的模式能匹配上的正在恢复的索引。
"rename_pattern": "test_(.+)",
#然后把它们重命名成替代的模式。
"rename_replacement": "test_$1"
}
这个会恢复 test_1 到你及群里,但是重命名成了 test_1
监控恢复进度:
如果你想监控恢复的进度,你可以使用 recovery API。这是一个通用目的的 API,用来展示你集群中移动着的分片状态。这个 API 可以为你在恢复的指定索引单独调用:
GET /test/_recovery
会得到以下信息:
{
"test" : {
"shards" : [
{
"id" : 0,
"type" : "SNAPSHOT",
"stage" : "DONE",
"primary" : true,
"start_time_in_millis" : 1585447584057,
"stop_time_in_millis" : 1585447585612,
"total_time_in_millis" : 1555,
"source" : {
"repository" : "my_backup",
"snapshot" : "test",
"version" : "7.6.0",
"index" : "test",
"restoreUUID" : "MOGiVjBgTc2dehMS_AtPkg"
},
"target" : {
"id" : "g_dpNRPIRAencHFM5zzzgA",
"host" : "192.168.1.6",
"transport_address" : "192.168.1.6:9300",
"ip" : "192.168.1.6",
"name" : "es4"
},
"index" : {
"size" : {
"total_in_bytes" : 7958,
"reused_in_bytes" : 0,
"recovered_in_bytes" : 7958,
"percent" : "100.0%"
},
"files" : {
"total" : 18,
"reused" : 0,
"recovered" : 18,
"percent" : "100.0%"
},
"total_time_in_millis" : 1382,
"source_throttle_time_in_millis" : 0,
"target_throttle_time_in_millis" : 0
},
"translog" : {
"recovered" : 0,
"total" : 0,
"percent" : "100.0%",
"total_on_start" : 0,
"total_time_in_millis" : 99
},
"verify_index" : {
"check_index_time_in_millis" : 0,
"total_time_in_millis" : 0
}
},
{
"id" : 0,
"type" : "PEER",
"stage" : "DONE",
"primary" : false,
"start_time_in_millis" : 1585447586910,
"stop_time_in_millis" : 1585447587518,
"total_time_in_millis" : 608,
"source" : {
"id" : "g_dpNRPIRAencHFM5zzzgA",
"host" : "192.168.1.6",
"transport_address" : "192.168.1.6:9300",
"ip" : "192.168.1.6",
"name" : "es4"
},
"target" : {
"id" : "KcHypMApQX-Ek5ASV2QdPA",
"host" : "192.168.1.8",
"transport_address" : "192.168.1.8:9300",
"ip" : "192.168.1.8",
"name" : "es6"
},
"index" : {
"size" : {
"total_in_bytes" : 7957,
"reused_in_bytes" : 0,
"recovered_in_bytes" : 7957,
"percent" : "100.0%"
},
"files" : {
"total" : 18,
"reused" : 0,
"recovered" : 18,
"percent" : "100.0%"
},
"total_time_in_millis" : 285,
"source_throttle_time_in_millis" : 0,
"target_throttle_time_in_millis" : 0
},
"translog" : {
"recovered" : 0,
"total" : 0,
"percent" : "100.0%",
"total_on_start" : 0,
"total_time_in_millis" : 236
},
"verify_index" : {
"check_index_time_in_millis" : 0,
"total_time_in_millis" : 0
}
}
]
}
}
type 字段告诉你恢复的本质;这个分片是在从一个快照恢复;
source 哈希描述了作为恢复来源的特定快照和仓库;
percent 字段让你对恢复的状态有个概念。这个特定分片目前已经恢复了 100% 的文件;它已经完成了。
取消一个恢复:
要取消一个恢复,你需要删除正在恢复的索引。因为恢复进程其实就是分片恢复,发送一个 删除索引 API 修改集群状态,就可以停止恢复进程。比如:
DELETE /test
如果test 正在恢复中,这个删除命令会停止恢复,同时删除所有已经恢复到集群里的数据。