shell脚本---实现es备份导出到本地形成json文件

项目需求:备份es数据,并落实到本地形成文件
脚本实现:定时备份es数据,定期删除备份文件,自定义文件名称、版本号,可以指定备份索引,也可以备份全部索引
使用esdump来进行备份:
ElasticDump是一个ElasticSearch的数据导入导出开源工具包,方便使用。

官方地址:官方地址:https://github.com/taskrabbit/elasticsearch-dump

安装方式如下:
安装NodeJS
下载源码:wget http://nodejs.org/dist/v0.10.32/node-v0.10.32-linux-x64.tar.gz
解压:tar xvf node-v0.10.22-linux-x64.tar.gz
配置环境变量:
在/etc/profile文件新增:

export NODE_HOME=/home/node-v0.10.0-linux-x64
export PATH=$PATH:$NODE_HOME/bin
export NODE_PATH=$NODE_HOME/lib/node_modules

执行 source /etc/profile 命令让环境变量设置生效
测试:在终端输入node -v如果有版本信息输出,则说明安装成功

安装NPM
curl -L https://npmjs.org/install.sh | sh

安装ElasticDump
npm install elasticdump -g
elasticdump
脚本内容:

#!/bin/bash
#全备方式
#作者:lcm_linux
#时间:2019.08.06
. /etc/profile
. ~/.bash_profile
source /etc/profile    #加载系统环境变量
source ~/.bash_profile  #加载用户环境变量
#set -o nounset       #引用未初始化变量时退出
#set -o errexit      #执行shell命令遇到错误时退出
#es备份存储路径,根据需要修改
backup_path="/data1/es_data/es_bak/data"
backup_log_path="/data1/es_data/es_bak/logs"
#获取当天日期
date=$(date +%Y-%m-%d_%H-%M-%S)
del_date=$(date +%Y-%m)
#远程访问ES集群的IP,需要按需修改
export_ip="192.168.162.222"
#远程访问ES集群的端口,内部通信,一般不需要修改
export_port="9200"
#备份输出的日志信息
backup_log="${backup_log_path}/es_export_${date}.log"
#backup_error_log="${backup_path}/es_export_error_${date}.log"
day=0
#获取索引列表
#定义文件1
list1=${backup_path}/es_export_list1.txt
#定义文件2
list2=${backup_path}/es_export_list2.txt
#定义文件3
list3=${backup_path}/es_export_list3.txt

function create_list(){
#获取除了 swordfish 以外的索引名称,可根据具体修改
#curl http://${export_ip}:${export_port}/_cat/indices |grep -v "swordfish" > ${list1}
#获取匹配到的所有索引名称 指定索引 grep -i "xxx" 满足任意条件过滤: grep -E "aaa|bbb|ccc*" 带*的要放在最后
curl http://${export_ip}:${export_port}/_cat/indices | grep -E "k007_dw_net_*" > ${list1}
cat ${list1} | awk '{print $3 "\t\t" $4}' > ${list2}
column -t ${list2} >  ${list3}
cat ${list3} | awk '{print $1}' | sort >> ${backup_path}/list.txt
rm -rf ${list1} ${list2} ${list3}
#打印行数
row=$(cat ${backup_path}/list.txt | wc -l)

echo "=========${date}:索引目录导出完成:此时行数:$row=======" >> ${backup_log}


}

#创建备份路径
if [[ ! -d ${backup_path}/${date} ]];then
  mkdir -p {$backup_path/${date},$backup_log_path}
else
  echo "========${date}:文件夹已经存在=======" >> ${backup_log}
fi

#清理备份路径下没有备份完全的文件夹
for f in `ls $backup_path`;
do
    if [[ $f = ${del_date}* ]]; then
        rm -rf $backup_path/$f
    fi
done

#创建备份路径
if [[ ! -d ${backup_path}/${date} ]];then
  mkdir -p {$backup_path/${date},$backup_log_path}
else
  echo "========${date}:文件夹已经存在=======" >> ${backup_log}
fi

#删除之前的备份
if [[ -f $backup_path/*.tar.gz ]];then
	find $backup_path/*.tar.gz -type f -mtime +$day -exec rm -rf {} \; > /dev/null 2>&1
fi

#===============开始导出数据=======================
echo "导出开始,结果查看 $backup_log"
echo "=========${date}:正在导出索引目录=======" >> ${backup_log}
#清理之前的索引列表文件
if [[ ! -f "${backup_path}/list.txt" ]]; then
	echo "正在创建索引list"
	create_list
else
	echo "正在删除旧的list"
	rm -f ${backup_path}/list.txt
	echo "删除完成,正在创建索引list"
	create_list
fi
sleep 5


#============检查是否存在elasticdump命令=================
command -v elasticdump >/dev/null 2>&1 || { echo >&2 "环境中没有检测到elasticdump,请确认是否存在,备份已中止!"; exit 1; }

sleep 5
echo "=========${date}:开始导出索引文件======="
echo "=========${date}:开始导出索引文件=======" >> ${backup_log}
        while read line
 	do
	elasticdump --input=http://${export_ip}:${export_port}/${line} --output="${backup_path}/${date}/"${line}_settings.json --type=settings --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }'
        sleep 5
	elasticdump --input=http://${export_ip}:${export_port}/${line} --output="${backup_path}/${date}/"${line}_analyzer.json --type=analyzer --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }'
        sleep 5
	elasticdump --input=http://${export_ip}:${export_port}/${line} --output="${backup_path}/${date}/"${line}_mapping.json --type=mapping --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }' 
        sleep 5
	elasticdump --input=http://${export_ip}:${export_port}/${line} --output="${backup_path}/${date}/"${line}_data.json --type=data --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }'
  if [[ $? == 0 ]];then
    cd $backup_path/${date}
    size1=$(du $backup_path/${date}/${line}_mapping.json -sh | awk '{print $1}')
    size2=$(du $backup_path/${date}/${line}_data.json -sh | awk '{print $1}')
    size3=$(du $backup_path/${date}/${line}_settings.json -sh | awk '{print $1}')
    size4=$(du $backup_path/${date}/${line}_analyzer.json -sh | awk '{print $1}')
    echo "导出时间:${date} 导出方式:elasticdump 导出索引:${line} mapping大小:$size1 data大小:$size2 settings大小:$size3 analyzer大小:$size4 导出状态:成功!" >>$backup_log
  else
    cd $backup_path/${date}
    echo "导出时间:${date} 导出方式:elasticdump 导出索引:${line} 导出状态:失败,请查看日志." >>$backup_log
  fi

  done < ${backup_path}/list.txt


  cd $backup_path
  tar zcpvf elasticdump_$date.tar.gz $date
  rm -rf $backup_path/$date
echo "导出结束,结果查看 $backup_log"
du elasticdump_$date.tar.gz -sh | awk '{print "文件:" $2 ",大小:" $1}'
echo "==========${date}:导出索引文件完成==========" >>$backup_log
echo "==========${date}:导出索引文件完成=========="

配置定时任务:

55 16 * * * /bin/bash /opt/script/es_shell/es_export.sh

附上恢复脚本A
脚本实现:根据上述备份脚本内容所产生的索引列表list,进行对list中索引数据恢复
脚本内容:

#!/bin/bash

#作者:lcm_linux
#时间:2019.08.06
#此导入脚本要结合导出脚本es_export.sh产生的es列表list.txt来一起使用,最好将两个脚本放在同一个目录下
source /etc/profile    #加载系统环境变量
source ~/.bash_profile  #加载用户环境变量
set -o nounset       #引用未初始化变量时退出
set -o errexit      #执行shell命令遇到错误时退出
date=$(date +%Y-%m-%d_%H-%M-%S)

function download(){
        while read line
        do
             elasticdump  --input=${1}/${line}_settings.json --output=http://${2}/${line} --type=settings --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }' 
                sleep 5
             elasticdump  --input=${1}/${line}_analyzer.json --output=http://${2}/${line} --type=analyzer --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }' 
                sleep 5
             elasticdump  --input=${1}/${line}_mapping.json --output=http://${2}/${line} --type=mapping --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }' 
                sleep 5
             elasticdump --input=${1}/${line}_data.json --output=http://${2}/${line} --type=data --searchBody '{"query": { "match_all": {} }, "stored_fields": ["*"],"_source": true }' 
        done < list.txt
}


function check(){

        if [ `npm ls elasticdump >/dev/null && echo $?` != 0 ];then
                npm install elasticdump
                cp /node_modules/elasticdump/bin/elasticdump /usr/sbin/
                echo "elasticdump 安装完成..."
        else
                echo "elasticdump 已经正常安装!!"
        fi
}


read -p "确定elasticdump是否正确安装?(y/n):" judge
if [ $judge = 'y' -o $judge = 'Y' ];then
        read -p "请输入es的数据存储的位置 : " floder
        read -p "请输入es集群的IP和端口,eg:172.16.3.139:9200 : " IPinfo

        download ${floder} ${IPinfo}

else
        echo "检查安装并且开始下载任务"
        check
        read -p "请输入es的数据存储的位置 : " floder
    	read -p "请输入es集群的IP和端口,eg:192.168.162.222:9200 : " IPinfo
        download ${floder} ${IPinfo}
fi

附上脚本B:
脚本实现:根据上述备份脚本所产生的索引文件list,进行对es中索引的删除
脚本内容:

#!/bin/bash
while read line
do
  curl -X DELETE http://192.168.162.222:9200/${line}
done < list.txt

总结
1)如果不导入analyzer会怎么样?
我试过如果只导入data和mapping,则数据会导入,mapping会发生变化,最终的结果没有分词的效果。
2)如果不导入mapping也不会有分词的效果。
3)顺序导入最好按照:analyzer,setting,mapping和data这个顺序来,防止出现分词失效的结果。导出顺序没有要求。

你可能感兴趣的:(shell)