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