Elasticsearch索引备份与迁移
总结Elasticsearch各种备份与迁移方案,亲测。
详细记录了具体步骤。
一、环境
- Ubuntu 14.04/16、04
- JDK1.8
- Elasticsearch 5.3
- Kibana 5.3.2
二、单节点环境
1. 创建备份存储目录
sudo mkdir /media/es/es_backup
# 该目录要是elasticsearch可访问的,我们的环境一般是elasticsearch用户
chown -R elasticsearch:elasticsearch /media/es/es_backup/
2. 修改elasticsearch.yml文件
修改 elasticsearch.yml 文件,添加 path.repo 配置。
vim elasticsearch.yml
# 增加一行如下:
path.repo: ["/media/es/es_backup"]
3. 重启Elasticsearch
4. 创建仓库
借助 Kibana 操作。
# 创建仓库,创建一个名为my_backup的仓库
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/media/es/es_backup",
"compress": true
}
}
# 检查仓库是否创建成功(my_backup为之前创建的仓库名称)
GET _snapshot/my_backup
# 删除仓库
DELETE _snapshot/my_backup
5. 备份索引数据
# 给所有索引创建快照
PUT _snapshot/my_backup/snapshot_name
# 针对具体的index创建快照备份
# 其中my_backup是仓库名称,snapshot_name是快照的名字
# ignore_unavailable在创建快照的过程中会忽略不存在的索引,默认情况下,如果没有设置,在索引不存在的情况下快照请求将会失败
# include_global_state能够防止集群的全局状态被作为快照的一部分存储起来
# 多个索引间不要加空格,否则只会对第一个索引操作(我踩过坑!!!)
PUT _snapshot/my_backup/snapshot_name?wait_for_completion=true
{
"indices": "index_1,index_2",
"ignore_unavailable": true,
"include_global_state": false
}
# 查看指定仓库下所有快照
GET _snapshot/my_backup/_all
# 查看具体某一个快照的信息
GET _snapshot/my_backup/snapshot_name/_status
# 删除快照,要指定仓库名和快照名
# 也能用于取消一个正在进行的快照创建过程,会删除备份了一半的快照
DELETE _snapshot/my_backup/snapshot_name
这里我取一个仓库名为 my_backup,快照名为 alert_snap,要备份的 index 为 .nina_view 和 cc-zabbix-2018.01.05。
6. 将数据迁移到另一个环境
# 备份创建好之后,在仓库目录/media/es/es_backup里是这样的:
-rw-r--r-- 1 elasticsearch elasticsearch 317 Jan 22 17:44 index-0
-rw-r--r-- 1 elasticsearch elasticsearch 8 Jan 22 17:44 index.latest
drwxr-xr-x 4 elasticsearch elasticsearch 4096 Jan 22 17:44 indices/
-rw-r--r-- 1 elasticsearch elasticsearch 103 Jan 22 17:44 meta-9KWgeCYtSBqqVrfD42bsNw.dat
-rw-r--r-- 1 elasticsearch elasticsearch 237 Jan 22 17:44 snap-9KWgeCYtSBqqVrfD42bsNw.dat
7. 在目标环境下,重复上面1~4步,建立仓库
将源集群的备份内容(/media/es/es_backup 里的所有文件),复制到迁移目标的仓库目录里,接下来就是类似批量导入了。
# 如果索引已经存在目标的集群,需要先关闭索引,恢复数据后再开启
POST /index_name/_close
POST _snapshot/my_backup/snapshot_name/_restore
POST /index_name/_open
# 从快照中恢复指定的索引,并给索引重命名
# indices里面可以写多个索引名,中间用逗号隔开
# rename_pattern可以写完整的索引名,也可以用正则匹配索引名的局部
# rename_replacement将替换rename_pattern中匹配到的局部(如果是正则,不是将整个索引名都替换)
#下面这条语句会把index_1,index_2恢复为restored_index_1和restored_index_2
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "index_1,index_2",
"rename_pattern": "index_(.+)",
"rename_replacement": "restored_index_$1"
}
# 查看恢复的状态
GET _snapshot/my_backup/snapshot_name/_status
三、集群-多节点环境
1. 创建共享目录
(todo…我没实施过,感觉挺麻烦的,不太推荐)
使用 sshfs 在 ES 集群中每个节点的相同位置挂载一个共享目录。
假设 ES 集群有三个节点:192.168.1.10,192.168.1.11,192.168.1.12,
我这里共享目录用了 /data/es_backup,ES 备份仓库目录(也是共享目录的挂在点)用了 /mnt/es_backup,可以根据实际情况调整。
# 在每个节点上安装sshfs
sudo apt-get install sshfs
# 选取其中一个节点的目录(非系统盘)作为共享目录 </br>
# 假设选择的节点ip为192.168.1.10:
mkdir /data/es_backup
chown -R elasticsearch:elasticsearch /data/es_backup
chmod -R 777 /data/es_backup
# 在每个ES节点的相同位置创建存放ES仓库的目录
mkdir /mnt/es_backup
chown -R elasticsearch:elasticsearch /mnt/es_backup
chmod -R 777 /mnt/es_backup
# 每个节点挂载共享目录,执行同样的操作。$user为用户,一般为root,回车后输入密码,其中的参数-o allow_other允许了其他用户访问这个目录
sshfs $user@192.168.1.10:/data/es_backup /mnt/es_backup -o allow_other
# 如果修改了默认ssh端口, 比如23566, 则可以这样:
sshfs $user@192.168.1.10:/data/es_backup /mnt/es_backup -p 23566 -o allow_other
# 测试运行ES的用户是否有对共享目录的写权限
sudo su - elasticsearch
touch /mnt/es_backup/test.txt
# 修改每个节点的elasticsearch.yml文件,添加path.repo配置
path.repo: ["/mnt/es_backup"]
接下来的操作和上面单节点一样,重启 es,建立仓库,创建快照等等。
# 在共享目录下为集群创建共享仓库
PUT _snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/mnt/es_backup",
"compress": true
}
}
# 后面步骤省略...
最后补充一下:取消挂载共享目录,不要直接删除挂载目录,在每个节点下执行下面命令:
# 这个命令会断开远程连接同时清空 /mnt/es_backup 目录。
fusermount -u /mnt/es_backup
类似的实现文件共享的方法还有 nfs 和 samba(支持 window 和 linux 互相访问)。
2. 借助第三方工具
第三方迁移工具,网上看了下,主要有三个:
- elasticsearch-dump
- elasticsearch-exporter
- elasticsearch-migration
优点:方便,快速。支持的功能很多(数据迁移、mapping迁移等等)。
缺点:原理是用了 scroll+bulk,百万、千万级别条数的数据可以使用,数据量过大还是老老实实用我上面整理的快照方法吧。
备注:对 ES 操作时候,一些报错没有捕获到并写入 log。比如我们只允许自动创建 cc-
开头的索引,迁移生成的新索引需要改名为别的名字,你会发现迁移完,数据没有进去,这也算是第三方工具的不足之处,不过它应该会不断完善。
四、总结
不管是运维也好,开发也好,对数据的备份和迁移是经常要做的事。针对环境的不同特别是数据量的差异,需要适时选择合适的方式。
有时候也要根据自己的具体需求而定,比如为了辅助自己开发,需要回放数据,那完全可以编写一些简单的脚本来实现。
我写过几个简单的脚本,放在 GitHub 上:
- es_replay
开发测试用途(数据导出、去重、构造和导入) - es_assistant
一些用于协助开发和测试的 es 交互脚本 - es_monitor
Elaticsearch 部署机的信息采集脚本(这个是很久很久以前写的,那时候刚学 ES,能直接用,功能上没问题,但代码完全可以更优化一下,最近忙着学其他东西,所以一直没去动它。)