需求一:elasticsearch中的数据需要每天备份
需求二:elasticsearch5.2中的数据要迁移到elasticsearch6.5.4中
方案:采用repository-hdfs插件进行数据的迁移备份和还原
疑问一
elasticsearch本来分布式有副本为什么要备份数据??
任何一个存储数据的软件,都需要定期的备份我们的数据。es replica提供了运行时的高可用保障机制,可以容忍少数节点的故障和部分数据的丢失,但是整体上却不会丢失任何数据,而且不会影响集群运行。但是replica没法进行灾难性的数据保护,比如说机房彻底停电,所有机器全部当即,等等情况。对于这种灾难性的故障,我们就需要对集群中的数据进行备份了,集群中数据的完整备份
疑问二
ES为什么采用hdfs备份
要备份集群数据,就要使用snapshot api。这个api会将集群当前的状态和数据全部存储到一个外部的共享目录(HDFS)中去。而且备份过程是非常智能的,第一次会备份全量的数据,但是接下来的snapshot就是备份两次snapshot之间的增量数据了。数据是增量进入es集群或者从es中删除的,那么每次做snapshot备份的时候,也会自动在snapshot备份中增量增加数据或者删除部分数据。因此这就意味着每次增量备份的速度都是非常快的。
废话不多了,开始吧
es5.2和es6.5分别按照repository-hdfs插件,我都是在线安装的,这个简单,如果有需求的话 我后期可以补上
1 在es5.2中备份数据
#0 环境说明 nameNode高可用 192.168.8.21(active)192.168.8.22(standby)
# 1 基于hdfs创建仓库
PUT /_snapshot/my_hdfs_repository
{
"type": "hdfs",
"settings": {
"uri": "hdfs://192.168.8.21:8020/",
"path": "elasticsearch/respositories/my_hdfs_repository",
"conf.dfs.client.read.shortcircuit": "true",
"max_snapshot_bytes_per_sec" : "50mb",
"max_restore_bytes_per_sec" : "50mb"
}
}
# 提出一个问题哈 我们的namenode 生产上 都是高可用 如果192.168.8.21这个namenode变成了standby的,那么仓库是否可用?
# 回答:上面的仓库不可用!!!
#解决方法 基于现在active的name在init一下仓库的地址即可
PUT /_snapshot/my_hdfs_repository
{
"type": "hdfs",
"settings": {
"uri": "hdfs://192.168.8.22:8020/",
"path": "elasticsearch/respositories/my_hdfs_repository",
"conf.dfs.client.read.shortcircuit": "true",
"max_snapshot_bytes_per_sec" : "50mb",
"max_restore_bytes_per_sec" : "50mb"
}
}
# 2 验证
POST /_snapshot/my_hdfs_repository/_verify
# 3 结果
{
"nodes": {
"avi9bA0AQeG7vHNtJCqPAA": {
"name": "node-5"
},
"JD16f2hASOCp3lXb5BlFRA": {
"name": "node-4"
},
"BtaGkSuWQGG57ApoASPm7w": {
"name": "node-3"
}
}
}
# 4 对指定的索引进行snapshotting备份
PUT _snapshot/my_hdfs_repository/snapshot_1
{
"indices": "poc13,poc8",
"ignore_unavailable": true,
"include_global_state": false,
"partial": true
}
#indices 也支持 poc*
# 5 查看snapshot_1备份信息 进度
GET /_snapshot/my_hdfs_repository/snapshot_1
# "state": "SUCCESS": 表示备份成功
2 在es6.5中还原数据
# 1 创建仓库的信息
PUT /_snapshot/my_hdfs_repository
{
"type": "hdfs",
"settings": {
"uri": "hdfs://192.168.8.21:8020/",
"path": "elasticsearch/respositories/my_hdfs_repository",
"max_snapshot_bytes_per_sec" : "100mb",
"max_restore_bytes_per_sec" : "100mb"
}
}
#2 还原数据 恢复指定的索引 并且进行重命名
# 将es备份的poc8库的数据 重命名为poc15
POST /_snapshot/my_hdfs_repository/snapshot_1/_restore
{
"indices": "poc8",
"ignore_unavailable": true,
"include_global_state": true,
"rename_pattern": "poc8",
"rename_replacement": "poc15"
}
# 3 监控还原restore的进度
GET poc8/_recovery
#4 删除历史snapshot_1备份
DELETE /_snapshot/my_hdfs_repository/snapshot_1
3 定期备份shell脚本
hdfs保存7天的备份数据,每天凌晨备份昨天的数据,并将备份的结果写到es库中,在kibana中图表展示是否备份成功
#!/bin/bash
#在windows编写的代码可能运行有问题执行以下 1>vim redisshell.sh 2>:set ff=unix
esip=192.168.8.23
esbakindex=poc14,poc8
#需要提前创建eslogindex的mapping信息
eslogindex=poc9/resultdata9
esbakfile=/bigdata/bak/es/baklogs
day1=$(date -d -1day +%Y%m%d)
day7=$(date -d -7day +%Y%m%d)
transTime=$(date '+%Y-%m-%d')
if [ ! -d $esbakfile ]; then
mkdir -p $esbakfile
fi
echo -e "\r\n" >> $esbakfile/bak_es_log.logs
echo "=================start====$(date '+%Y-%m-%d %H:%M:%S')=================" >> $esbakfile/bak_es_log.logs
#备份新的数据,指定新的索引库
param=`curl -XPUT "http://$esip:9200/_snapshot/my_hdfs_repository/snapshot_$day1?wait_for_completion=true" -d '{
"indices": "'${esbakindex}'",
"ignore_unavailable": true,
"include_global_state": false,
"partial": true
}'`
echo -e "\r\n" >> $esbakfile/bak_es_log.logs
result1=$(echo $param | grep "SUCCESS")
if [[ "$result1" != "" ]]; then
echo " create new snapshot_$day1 success" >> $esbakfile/bak_es_log.logs
#发送数据到es库
curl -XPUT "http://$esip:9200/${eslogindex}/${transTime}create" -d'
{
"transTime":"'$transTime'",
"operation":"create",
"snapshotname":"snapshot_'$day1'",
"status":"success"
}'
else
echo -e "create new snapshot_$day1 fail !!! " >> $esbakfile/bak_es_log.logs
echo -e ${param} >> $esbakfile/bak_es_log.logs
curl -XPUT "http://$esip:9200/${eslogindex}/${transTime}create" -d'
{
"transTime":"'$transTime'",
"operation":"create",
"snapshotname":"snapshot_'$day1'",
"status":"fail"
}'
fi
echo -e "\r\n" >> $esbakfile/bak_es_log.logs
#删除7天以前的数据
param2=`curl -XDELETE "http://$esip:9200/_snapshot/my_hdfs_repository/snapshot_$day7?pretty"`
result2=$(echo $param2 | grep "acknowledged")
if [[ "$result2" != "" ]]; then
echo " delete snapshot_$day7 success " >> $esbakfile/bak_es_log.logs
curl -XPUT "http://$esip:9200/${eslogindex}/${transTime}delete" -d'
{
"transTime":"'$transTime'",
"operation":"delete",
"snapshotname":"snapshot_'$day7'",
"status":"success"
}'
else
echo " delete snapshot_$day7 fail !!! " >> $esbakfile/bak_es_log.logs
echo $param2 >> $esbakfile/bak_es_log.logs
curl -XPUT "http://$esip:9200/${eslogindex}/${transTime}delete" -d'
{
"transTime":"'$transTime'",
"operation":"delete",
"snapshotname":"snapshot_'$day7'",
"status":"fail"
}'
fi
echo -e "\r\n" >> $esbakfile/bak_es_log.logs
echo "======================end====$(date '+%Y-%m-%d %H:%M:%S')=======================" >> $esbakfile/bak_es_log.logs