天天看點

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這個順序來,防止出現分詞失效的結果。導出順序沒有要求。