ES备份与迁移-踩坑文档
背景介绍
因业务需求,现有一个ES2.2.x版本的集群的数据需要进行归档并把该EC2销毁。
思路分析
- ES集群官方所支持的备份方式都有哪些?是否有第三方工具可以更快解决这个需求?
- 现有的生产测试等集群版本全部都是5.5.0,原有2.2.x版本的数据是否可以正确导入到现有集群中,会不会出现不兼容的情况?
- 如何确保迁移备份后的数据的准确性?
实现流程
实现流程就是我的踩坑过程,可以跳过直接看总结的实践方案
官方支持的备份方式
官方所提供的备份方式为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 | curl -XPUT "http://new.2.2.x.node:9200/_snapshot/my_backup" -H "Content-Type: application/json" -d '{ |
执行如下命令创建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 | curl -XPUT "http://new.5.5.0.node:9200/_snapshot/my_backup" -H "Content-Type: application/json" -d '{ |
通过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 | curl -XPOST "http://test.cluster:9200/_snapshot/my_backup/5.5.0-es-backup-20180807/_restore?wait_for_completion=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的方法会保证数据的一致性。
实践方案
明确生产系统是需要做什么操作:
- 需要定期备份数据:采用snapshot方式,直接调用API将备份文件直接存储到S3,并写脚本实现定期全量备份。
- 需要升级ES一个大版本版本:采用snapshot方式,参考官方no-down-time-update备份后数据后逐个节点进行二进制文件升级。
- 需要跨大版本升级ES或迁移ES集群:采用第三方工具Elasticsearch-Migration,新建同性能的中转集群进行数据中转,或迁移完成直接废弃原有集群。
注意要点
数据尽量存储到S3,或者本地产生Snapshot然后上传到S3,保障数据安全性第一。
注意与ES所关联的其他工具,如Kibana和Logstash,他们与ES关联可能会产生属于他们自己的index,这些index一般情况下不建议迁移,可能导致Kibana等配置失效或排版错乱。
迁移或备份前请计算好大致所需资源用量,闲时备份,小心可能会对提供的服务有影响。
参考资料:
引用自网络,不保证链接的可用性,排名不分先后,感谢原作者的付出
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