ES备份与迁移-踩坑文档

背景介绍

因业务需求,现有一个ES2.2.x版本的集群的数据需要进行归档并把该EC2销毁。

思路分析

  1. ES集群官方所支持的备份方式都有哪些?是否有第三方工具可以更快解决这个需求?
  2. 现有的生产测试等集群版本全部都是5.5.0,原有2.2.x版本的数据是否可以正确导入到现有集群中,会不会出现不兼容的情况?
  3. 如何确保迁移备份后的数据的准确性?

实现流程

实现流程就是我的踩坑过程,可以跳过直接看总结的实践方案

官方支持的备份方式

官方所提供的备份方式为Snapshot(快照),官方所支持的迁移方式一共有四种,分别为:Elasticsearch-Dump、Elasticsearch-Exporter、Logstash、Elasticsearch-Migration

确定方案

第一时间想到的方法便是使用官方提供的方案对现有集群做Snapshot,并且该方法可以通过安装插件的方式直接备份到我们的S3桶中,但是由于该集群不允许SSH登陆,因此这个方案并不可行。

无法登陆SSH则无法获取到集群配置文件中对于备份位置的设置,因此也无法通过集群的API调用产生备份。官方的默认备份方案不能使用,思路转移到对该集群进行迁移上来,因为该集群并没有设置用户名密码,并且提供了所有权限,可以对集群进行读取和写入,因此官方支持的第三方迁移工具可以派上用场了。

通过简单调研发现Elasticsearch-Migration最为符合我们这个需求,其他的方式要么需要SSH登陆,要么需要翻墙安装许多工具和包,这个方案只需要去Github下载二进制文件并配置JDK即可开箱使用,并且支持导出文件和直接集群迁移等多种方式。

确定好方案以后初步思路如下:新建一台性能合适的EC2,并搭建好2.2.x版本的ES单节点服务,在该EC2上使用ES-migration工具把现有集群进行迁移操作,通过直接克隆的方式把原集群直接克隆到本地单节点上,在对本地单节点进行下一步的操作。

操作记录

对集群进行迁移

1
./esm -s http://old.cluster:9200 -d http://new.2.2.x.node:9200 -a

这个命令直接把原有集群克隆并不行,命令报错,查询一番发现这个问题还没有人遇到,可能是版本过老,也有可能是工具的bug。Anyway,工具的dump到文件的功能依旧还是正常的,因此使用命令将其index遍历一遍,并生成对应各个index的备份文件。

对所有index进行备份

1
curl "http://old.cluster:9200/_cat/indices?v" | sed '1d' | awk '{print $2}' | while read index;do ./esm -s http://old.cluster:9200 -x "$index"--copy_settings --copy_mappings -o "$index".dump;done

这个命令执行过程中可能会产生报错,但是并不影响结构,报错原因是创建了一个空的index并且该index并没有任何数据,工具便不会创建空文件。

重要!重要!重要! 创建EC2的时候请创建一个性能较强的型号,并且挂在一个单独的SSD硬盘,否则会把EC2写挂。以本次数据为例,大约数据量为15G左右,配置为m4.2xlarge(8C32G)和两块100G的SSD。

备份完成后将esm程序和备份好的文件一同移动到另一块盘里,因为AWS是以每块盘来计算IOPS的,100G的SSD的为300/3000,这种业界的计算方式根据以往的经验需要购买至少两块盘,对向写入,否则肯定会把磁盘IO撑爆。事实证明,通过iostat命令查看其磁盘确实是已经超过单盘最大突增IOPS的50%以上。

对所有index进行恢复

1
curl "http://old.cluster:9200/_cat/indices?v" | sed '1d' | awk '{print $2}' | while read index;do ./esm -d http://new.2.2.x.node:9200 -x "$index"--copy_settings --copy_mappings -i "$index".dump;done

上述命令会把备份出来的文件恢复到新单节点。等待其恢复完毕,然后将节点停止,并修改配置文件 elasticsearch.yml,添加一行

配置信息 按照实际情况修改

path.repo: ["/mount/backups", "/mount/longterm_backups"]

重启节点的服务,此时刚刚配置的备份目录已经将加载到配置中,执行如下命令创建备份仓库

创建备份仓库

1
2
3
4
5
6
7
curl -XPUT "http://new.2.2.x.node:9200/_snapshot/my_backup" -H "Content-Type: application/json" -d '{
"type": "fs",
"settings": {
"location": "/mnt/disk1/backups/my_backup", // 也可以使用相对路径 即只填写my_backup,两个写法是一样的效果
"compress": true
}
}'

执行如下命令创建snapshot_1的备份。?wait_for_completion=true这个可以不加,不加则放到后台跑备份任务。

产生快照

1
curl -XPUT "http://new.2.2.x.node:9200/_snapshot/my_backup/snapshot_1?wait_for_completion=true"

这样,基于2.2.x版本的快照就已经制作好了,如果觉得不放心,可以把ES的data文件夹删除掉,然后用刚才创建的snapshot_1的快照来测试恢复

恢复快照

1
curl -XPOST "http://new.2.2.x.node:9200/_snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true"

接下来是需要给目前的2.2.x版本进行升级,把数据升级到5.5.0可以识别的格式。尝试将Snapshot复制到新建的5.5.0单节点的备份目录中,然后创建5.5.0的备份仓库。

创建备份仓库

1
2
3
4
5
6
7
curl -XPUT "http://new.5.5.0.node:9200/_snapshot/my_backup" -H "Content-Type: application/json" -d '{
"type": "fs",
"settings": {
"location": "/mnt/disk2/backups/my_backup", // 也可以使用相对路径 即只填写my_backup,两个写法是一样的效果
"compress": true
}
}'

通过2.2.x的版本快照恢复到5.5.0,则出现报错,原因是某些index无法升级,阅读过官方文档得知ES最多支持一个大版本的升级,即2.2.x最高升级到3.x.x,以此类推升级到5.5.0则需要连续升级两次,选用Elasticsearch-Migration的优势由此体现出来,esm可以直接把2.x的版本数据直接迁移到最高5.x,日后升级6.x的话这个工具依旧可以使用。执行如下命令,通过集群迁移的方式直接导入到5.5.0节点中。

通过集群迁移的方式导入数据

1
curl "http://new.2.2.x.node:9200/_cat/indices?v" | sed '1d' | awk '{print $2}' | while read index;do ./esm -s http://new.2.2.x.node:9200 -d http://new.5.5.0.node:9200 -x "$index"--copy_settings --copy_mappings;done

OR 执行如下命令,通过备份文件的方式导入数据

通过备份文件的方式导入数据

1
curl "http://new.2.2.x.node:9200/_cat/indices?v" | sed '1d' | awk '{print $2}' | while read index;do ./esm -d http://new.5.5.0.node:9200 -x "$index"--copy_settings --copy_mappings;done -i "$index".dump;done

等待导入完毕,当前5.5.0版本的ES则顺利把原2.2.x的数据迁移过来了,执行如下命令,产生5.5.0版本的备份文件

产生5.5.0快照

1
curl -XPUT "http://new.5.5.0.node:9200/_snapshot/my_backup/5.5.0-es-backup-20180807?wait_for_completion=true"

这样,基于5.5.0版本的快照就已经制作完成,压缩并拷贝整个目录到测试集群进行恢复测试。测试集群也需要指定备份地址、创建备份仓库、产生备份快照操作,上述操作不再赘述。

如果执行报错某index处于open状态,则需要执行如下命令关闭。

1
curl -XPOST "http://test.cluster:9200/INDEX_NAME/_close"

如果恢复 .kibana 或其他类似的index时出现报错,例如Shard(分片)不同的错误,则是源版本与目标版本index版本不兼容的问题。比如本次实践中,2.2.x版本所依赖的Kibana产生的.kibana index是1 Shard,而5.5.0版本所依赖的Kibana产生的.kibana index则是5 Shards,因此恢复产生错误实属正常,且该index应属于恢复排除项。因此恢复的时候应该执行如下命令。

对除去某些特殊index的所有index进行恢复

1
2
3
4
5
6
curl -XPOST "http://test.cluster:9200/_snapshot/my_backup/5.5.0-es-backup-20180807/_restore?wait_for_completion=true"
{
"indices": "$(curl 'http://new.5.5.0.node:9200/_cat/indices?v' | sed '1d' | awk '{print $2}' | grep -wv '.kibana' | tr '\n' ',')",
"ignore_unavailable": true,
"include_global_state": true
}

如果集群使用了Kibana,则按照上述方式关闭名为 .kibana 的index之后,还需要执行打开命令。否则Kibana无法正确连接并访问集群,会出现无限循环的重定向错误。

产生5.5.0快照

1
curl -XPOST "http://test.cluster:9200/.kibana/_open"

到这一步,基本所有需要的操作都已经搞定了,剩下只需要把备份的文件打包压缩一下,然后传到S3上做存贮即可。如下命令

上传S3

1
aws s3 cp /PATH/TO/YOUR/FILE/5.5.0-es-backup-20180807.tgz s3://YOUR/BUCKET/backups/

关于数据准确性,则需要对index是否齐全,并且检查每个index中相关条目是否准确,不过理论上说,官方提供的工具是带有校验功能的,因此Snapshot的方法会保证数据的一致性。

实践方案

明确生产系统是需要做什么操作:

  1. 需要定期备份数据:采用snapshot方式,直接调用API将备份文件直接存储到S3,并写脚本实现定期全量备份。
  2. 需要升级ES一个大版本版本:采用snapshot方式,参考官方no-down-time-update备份后数据后逐个节点进行二进制文件升级。
  3. 需要跨大版本升级ES或迁移ES集群:采用第三方工具Elasticsearch-Migration,新建同性能的中转集群进行数据中转,或迁移完成直接废弃原有集群。

注意要点

  1. 数据尽量存储到S3,或者本地产生Snapshot然后上传到S3,保障数据安全性第一。

  2. 注意与ES所关联的其他工具,如Kibana和Logstash,他们与ES关联可能会产生属于他们自己的index,这些index一般情况下不建议迁移,可能导致Kibana等配置失效或排版错乱。

  3. 迁移或备份前请计算好大致所需资源用量,闲时备份,小心可能会对提供的服务有影响


参考资料:

引用自网络,不保证链接的可用性,排名不分先后,感谢原作者的付出

https://www.elastic.co/guide/cn/elasticsearch/guide/current/backing-up-your-cluster.html

https://www.elastic.co/guide/en/elasticsearch/reference/6.2/modules-snapshots.html

http://blog.51cto.com/michaelkang/2057873?utm_source=oschina-app

https://blog.csdn.net/gamer_gyt/article/details/53230165

https://www.elastic.co/guide/en/elasticsearch/reference/5.5/docs-reindex.html#reindex-from-remote

http://cwiki.apachecn.org/pages/viewpage.action?pageId=9405386

https://blog.csdn.net/u010463032/article/details/78861984

https://stackoverflow.com/questions/28808998/elasticsearch-restore-snapshot-with-different-shards-number

https://blog.csdn.net/laoyang360/article/details/65449407

https://blog.csdn.net/crazyhacking/article/details/45726683

https://github.com/medcl/esm

https://blog.csdn.net/daiyutage/article/details/69253209

https://blog.csdn.net/hello_hwc/article/details/40118129

http://docs.amazonaws.cn/en_us/cli/latest/reference/s3/index.html

http://www.cnblogs.com/aresxin/p/8035137.html