常见的数据库都会提供备份的机制,以解决在数据库无法使用的情况下,可以开启新的实例,然后通过备份来恢复数据减少损失。虽然 Elasticsearch 有良好的容灾性,但由于以下原因,其依然需要备份机制。
常见的数据库都会提供备份的机制,以解决在数据库无法使用的情况下,可以开启新的实例,然后通过备份来恢复数据减少损失。虽然 Elasticsearch 有良好的容灾性,但由于以下原因,其依然需要备份机制。
- 数据灾备。在整个集群无法正常工作时,可以及时从备份中恢复数据。
- 归档数据。随着数据的积累,比如日志类的数据,集群的存储压力会越来越大,不管是内存还是磁盘都要承担数据增多带来的压力,此时我们往往会选择只保留最近一段时间的数据,比如1个月,而将1个月之前的数据删除。如果你不想删除这些数据,以备后续有查看的需求,那么你就可以将这些数据以备份的形式归档。
- 迁移数据。当你需要将数据从一个集群迁移到另一个集群时,也可以用备份的方式来实现。
Elasticsearch 做备份有两种方式,一是将数据导出成文本文件,比如通过 elasticdump、esm 等工具将存储在 Elasticsearch 中的数据导出到文件中。二是以备份 elasticsearch data 目录中文件的形式来做快照,也就是 Elasticsearch 中 snapshot 接口实现的功能。第一种方式相对简单,在数据量小的时候比较实用,当应对大数据量场景效率就大打折扣。我们今天就着重讲解下第二种备份的方式,即 snapshot api 的使用。
备份要解决备份到哪里、如何备份、何时备份和如何恢复的问题,那么我们接下来一个个解决。
一、备份到那里
在 Elasticsearch 中通过 repository 定义备份存储类型和位置,存储类型有共享文件系统、AWS 的 S3存储、HDFS、微软 Azure的存储、Google Cloud 的存储等,当然你也可以自己写代码实现国内阿里云的存储。我们这里以最简单的共享文件系统为例,你也可以在本地做实验。
首先,你要在 elasticsearch.yml 的配置文件中注明可以用作备份路径 path.repo ,如下所示:
注意:线上每个节点都要设置,同时要保证es启动用户的uid和gid是相同的
多路径:path.repo: ["/mount/backups", "/mount/longterm_backups"]单路径:path.repo: /home/work/es-test-2/es-tom1-8515/es_backup
配置好后,就可以使用 snapshot api 来创建一个 repository 了
1.1 创建一个名为 es_backup 的 repository
curl -PUT http://10.0.0.1:8520/_snapshot/es_backup/ -d '{ "type":"fs", "settings":{ "location":"/home/work/es-test-2/es-tom1-8515/es_backup", "max_snapshot_bytes_per_sec":"50mb", "max_restore_bytes_per_sec":"50mb", "compress":true }}'
这样就注册了一个名为es_backup的仓库,这里的location需要注意,最好是设置一个每个节点都能访问并且有写权限的共享目录,如smb目录等(如果整个集群就一个节点那么设置为本地目录也无所谓)。
除了location外,还有一些其他选项可以设置:
-
compress 是否压缩
-
max_snapshot_bytes_per_sec 制作快照的速度,默认20mb/s
-
max_restore_bytes_per_sec 快照恢复的速度,默认20mb/s
1.2 更新仓库设置
例子:
curl -XPOST http://192.168.0.1:9200/_snapshot/my_backup/{ "type": "fs", "settings": { "location": "/data/backups/elasticsearch", "max_snapshot_bytes_per_sec" : "50mb", "max_restore_bytes_per_sec" : "50mb", "compress" : true }}
1.3 检查注册的仓库信息
curl -XGET http://192.168.0.1:9200/_snapshot/my_backup
二、如何备份
2.1 进行数据备份
有了 repostiroy 后,我们就可以做备份了,也叫快照,也就是记录当下数据的状态。指定快照名称为snapshot_20190920
1)备份集群
curl -XPUT http://10.0.0.1:8517/_snapshot/es_backup/snapshot_20190920
执行上面的上面的命令会马上返回,并在后台执行备份操作, 如果想等到备份完成,可以加上参数wait_for_completion=true
2)备份索引
默认是备份所有的索引indices, 如果要指定index,可以这样
curl -XPUT http://192.168.0.1:9200/_snapshot/my_backup/snapshot_20150812{ "indices": "index_1,index_2"}
2.2 查看备份状态
curl -XGET http://10.0.0.1:8517/_snapshot/es_backup/snapshot_20190920/_status
主要由如下几种状态:
- INITIALIZING 集群状态检查,检查当前集群是否可以做快照,通常这个过程会非常快
- STARTED 正在转移数据到仓库
- FINALIZING 数据转移完成,正在转移元信息
- DONE 完成
- FAILED 备份失败
2.3 取消备份
例子:
curl -XDELETE http://192.168.0.1:9200/_snapshot/my_backup/snapshot_20150812
2.4 恢复备份
例子:
curl -XPOST http://192.168.0.1:9200/_snapshot/my_backup/snapshot_20190920/_restore
三、增量备份
通过上面的步骤我们成功创建了一个备份,但随着数据的新增,我们需要对新增的数据也做备份,那么我们如何做呢?方法很简单,只要再创建一个快照 20190921 就可以了。
curl -XPUT http://10.0.0.1:8517/_snapshot/es_backup/snapshot_20190921
当执行完毕后,你会发现 /mount/backups/my_backup 体积变大了。这说明新数据备份进来了。要说明的一点是,当你在同一个 repository 中做多次 snapshot 时,elasticsearch 会检查要备份的数据 segment 文件是否有变化,如果没有变化则不处理,否则只会把发生变化的 segment file 备份下来。这其实就实现了增量备份。
elasticsearch 的资深用户应该了解 force merge 功能,即可以强行将一个索引的 segment file 合并成指定数目,这里要注意的是如果你主动调用 force merge api,那么 snapshot 功能的增量备份功能就失效了,因为 api 调用完毕后,数据目录中的所有 segment file 都发生变化了。
另一个就是备份时机的问题,虽然 snapshot 不会占用太多的 cpu、磁盘和网络资源,但还是建议大家尽量在闲时做备份。
四、备份恢复
4.1 备份数据的恢复
所谓“养兵千日,用兵一时”,我们该演练下备份的成果,将其恢复出来。通过调用如下 api 即可快速实现恢复功能。
curl -XPOST http://10.0.0.1:8520/_snapshot/es_backup/snapshot_20190920/_restore
注意:
1)这里的恢复可以恢复到本地集群,也可以恢复到其他集群。如果需要将快照迁移到另一个集群.只需要将备份文件全部拷贝到要迁移的机器上, 然后再在新的集群上注册一个快照仓库,设置location
的位置为备份文件所在的地方,然后执行恢复备份的命令即可。
2)恢复集群中不能存在要恢复的索引,如果存在要删除
默认情况下,是恢复所有的索引,我们也可以设置一些参数来指定恢复的索引,以及重命令恢复的索引,这样可以避免覆盖原有的数据.
curl -XPOST http://192.168.0.1:9200/_snapshot/my_backup/snapshot_20150812/_restore{ "indices": "index_1", "rename_pattern": "index_(.+)", "rename_replacement": "restored_index_$1"}
- 上面的indices, 表示只恢复索引’index_1’
- renamepattern: 表示重命名索引以’index‘开头的索引.
- rename_replacement: 表示将所有的索引重命名为’restored_index_xxx’.如index_1会被重命名为restored_index_1.
4.2 查看恢复进度
# 查看所有索引的恢复进度curl -XGET http://192.168.0.1:9200/_recovery/# 查看索引restored_index_1的恢复进度curl -XGET http://192.168.0.1:9200/_recovery/restored_index_1恢复进度字段解释:id:分片idtype:恢复来源信息,gateway、snapshot(快照)、replica(副本)、relocating(重新分配);stage:恢复阶段,init(初始化,未开始)、index(读取索引元数据信息和正在从源复制数据到 目标上)、start(正在执行,打开索引以备使用)、translog(重新使用事务日志)、finalize(清除)、done(完成)。primary:true主分片,否则为false;start_time:开始恢复时间戳;stop_time:恢复完成时间戳;total_time_in_millis:分片恢复所耗的毫秒数;source:恢复源,如果是从快照恢复的描述为快照仓库,其他的为节点信息;target:目标节点;index:索引恢复统计信息;translog:事务日志恢复统计信息;start:打开索引的统计信息;
4.3 取消恢复
只需要删除索引,即可取消恢复
curl -XDELETE http://192.168.0.1:9200/restored_index_1
五、备份恢复注意事项
由于 Elasticsearch 版本更新比较快,因此大家在做备份与恢复的时候,要注意版本问题,同一个大版本之间的备份与恢复是没有问题的,比如都是 5.1 和 5.6 之间可以互相备份恢复。但你不能把一个高版本的备份在低版本恢复,比如将 6.x 的备份在 5.x 中恢复。而低版本备份在高版本恢复有一定要求:
1) 5.x 可以在 6.x 恢复
2) 2.x 可以在 5.x 恢复
3) 1.x 可以在 2.x 恢复
其他跨大版本的升级都是不可用的,比如1.x 的无法在 5.x 恢复。这里主要原因还是 Lucene 版本问题导致的,每一次 ES 的大版本升级都会伴随 Lucene 的大版本,而 Lucene 的版本是尽量保证向前兼容,即新版可以读旧版的文件,但版本跨越太多,无法实现兼容的情况也在所难免了。
详细可以参考:
https://www.elastic.co/guide/en/elasticsearch/reference/current/snapshot-restore.html
https://www.elastic.co/guide/en/elasticsearch/guide/2.x/backing-up-your-cluster.html