一、背景
生产上每天会产生数千个音频文件,大小有几个G。这些文件存放在cfs内,由于cfs使用费用较高,容量较小,需要定期手动转移至空间更大费用更小的bos内。本程序就是将手动操作改为自动化方式。涉及日志输出、文件比对、文件复制、文件删除、监控告警等。
二、名词解释
cfs:文件储存CFS是文件以及协议存储,可以理解为是更高一级的对象储存BOS,文件储存CFS不能做计算,只是网关协议存储,在图片及文件的读写、和安全上级别更高。
bos:对象储存BOS类似于百度云盘,不过是企业级的,对象储存BOS提供一个简单的 Web 服务接口,可用于存储和提取任意数量的数据。 cfs供多台服务器共享使用,使用费用比bos高很多。
三、程序工作逻辑
每天产生的大部分音频文件存放在以日期为名字的目录内,该目录还有一层子目录xxdata,小部分录音文件存放在这个子目录内。首先将n天前的cfs日期目录复制到bos,然后比对是否一致,比对包含md5和diff以及文件数量比较,若都一致则删除原cfs录音文件目录,若有一项不一致则退出,最后通过微信发出成功的通知或失败的告警。
四、日志说明
程序每一步操作都有详细的日志记录,包括源文件目录和目标目录是否存在、复制了哪些文件、删除了哪些文件、md5生成和比对、哪些操作失败了等。程序正常运行或者运行失败都能通过日志定位查看。
五、各模块介绍
本程序共有9个模块,下面一一介绍
1.日志模块logs_bak
代码语言:javascript复制logs_bak(){
cp ${LOCAL_LOG}/log.txt ${LOCAL_LOG}/log_${DATE}.txt
echo '' > ${LOCAL_LOG}/log.txt
cp ${ALTER_LOG}/alter.txt ${ALTER_LOG}/alter_${DATE}.txt
echo -n "" > ${ALTER_LOG}/alter.txt
cp ${MD5_LOG}/md5.txt ${MD5_LOG}/md5_${DATE}.txt
echo '' > ${MD5_LOG}/md5.txt
}
本程序共有4个日志,分别是all:记录本程序执行过程中的所有动作;alter:只记录各步骤出错内容,如果成功的话该日志为空;cron:记录每天定时任务执行情况;md5:记录md5生成和比对。
除了cron日志外,其它三个日志在程序运行的时候会以日期割接备份。
2.目录检查模块file_check
代码语言:javascript复制file_check(){
if [ -d ${SOURCE_PATH} ]
then
echo "the org_directory_file is existed,now you can cp files from ${SOURCE_PATH}/${DATE}" >> ${LOCAL_LOG}/log.txt
else
echo "there is no $DATE directory,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 101
fi
if [ -d ${DEST_PATH} ]
then
echo "the dest_directory is existed,now you can cp files to ${DEST_PATH}" >> ${LOCAL_LOG}/log.txt
else
echo "there is no bos directory,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 102
fi
}
检查源文件目录SOURCE_PATH和备份目录DEST_PATH是否存在,因为有可能出现cfs或者bos挂载失败的问题。若路径都在则继续否则报错并退出。
运行日志截图:
3.生成源文件md5值模块md5_a
代码语言:javascript复制md5_a(){
for list_a in `find ${SOURCE_PATH}/* ( -path $NODATA ) -prune -o -type f -print |grep -v md5`
do
FILE_NAME_A=${list_a##*/}
cd ${SOURCE_PATH}
md5sum ${FILE_NAME_A} >> ${SOURCE_PATH}/md5_a.txt
done
if [ "$?" -eq "0" ]
then
echo "the first md5 file md5_a.txt is created" | tee -a ${LOCAL_LOG}/log.txt ${MD5_LOG}/md5.txt
else
echo "the first md5 file md5_a.txt created fail,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 103
fi
}
获取日期目录第一层的音频文件列表并生成md5文件md5_a.txt,该文件在复制到bos后进行md5比对时会用到。若正常生成该文件则继续,否则写入告警日志并退出。
运行日志截图:
4.生成源文件md5值模块md5_b
代码语言:javascript复制md5_b(){
for list_b in `find ${NODATA} -type f -print | grep -v md5`
do
cd ${NODATA}
FILE_NAME_B=${list_b##*/}
md5sum ${FILE_NAME_B} >> ${NODATA}/md5_b.txt
done
if [ "$?" -eq "0" ]
then
echo "the second md5 file md5_b.txt is created" | tee -a ${LOCAL_LOG}/log.txt ${MD5_LOG}/md5.txt
else
echo "the second md5 file md5_b.txt created fail,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 104
fi
}
获取日期目录第二层的录音文件列表并生成md5文件md5_b.txt,该文件在复制到bos后进行md5比对时会用到。若正常生成该文件则继续,否则写入告警日志并退出。
运行日志截图:
5.文件复制模块file_cp
代码语言:javascript复制file_cp(){
echo "now ready to copy files from source to dest" | tee -a ${LOCAL_LOG}/log.txt
cp -R ${SOURCE_PATH} ${DEST_PATH} -vvv >> ${LOCAL_LOG}/log.txt
if [ "$?" -eq "0" ]
then
echo "the files copy sucessed" | tee -a ${LOCAL_LOG}/log.txt
else
echo "the files copy failed,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 105
fi
}
通过cp命令将录音文件由cfs复制到bos,复制过程中详细记录日志。若成功复制则继续,否则写入告警日志并退出。
运行日志截图:
6.md5比较模块diff_md5_a
代码语言:javascript复制diff_md5_a(){
cd ${DEST_PATH}/${DATE}
echo "this is md5_a compared log" >> ${MD5_LOG}/md5.txt
md5sum -c md5_a.txt >> ${MD5_LOG}/md5.txt
if [ "$?" -eq "0" ]
then
echo "the files in ${DATE} except nodata compared Ok" >> ${LOCAL_LOG}/log.txt
echo "md5_a Ok"
else
echo "the files in ${DATE} except nodata compared error,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 106
fi
}
在bos的首层目标目录运行'md5sum -c md5_a.txt'进行第一层的录音文件md5比对,若比对正常则继续,否则写入告警日志并退出。
运行日志截图:
7.md5比较模块diff_md5_b
代码语言:javascript复制diff_md5_b(){ #对目标目录第二层文件进行比对
cd ${DEST_PATH}/${DATE}/nodata
echo "this is md5_b compared log" >> ${MD5_LOG}/md5.txt
md5sum -c md5_b.txt >> ${MD5_LOG}/md5.txt
if [ "$?" -eq "0" ]
then
echo "the files nodata compared Ok" >> ${LOCAL_LOG}/log.txt
echo "md5_b Ok"
else
echo "the files nodata compared error,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 107
fi
}
在bos的第二层目标目录运行'md5sum -c md5_b.txt'进行第二层的录音文件md5比对,若比对正常则继续,否则写入告警日志并退出。
运行日志截图:
8.源文件删除模块org_file_rm
代码语言:javascript复制org_file_rm(){
diff ${SOURCE_PATH} ${DEST_PATH}/${DATE}
result1=$?
diff ${NODATA} ${DEST_PATH}/${DATE}/nodata
result2=$?
wc1=`ls -lR ${SOURCE_PATH} | grep "^-" | wc -l`
wc2=`ls -lR ${DEST_PATH}/${DATE} | grep "^-" | wc -l`
if [ ${result1} -eq "0" ] && [ ${result2} -eq "0" ] && [ ${wc1} -eq ${wc2} ]
then
echo "the files diff Ok, you can rm the source files" >> ${LOCAL_LOG}/log.txt
rm -rfv ${SOURCE_PATH} >> ${LOCAL_LOG}/log.txt
else
echo "the files diff error,please check" | tee -a ${LOCAL_LOG}/log.txt ${ALTER_LOG}/alter.txt
exit 108
fi
}
自动化删除源录音文件前会进行首层和第二层的diff比对以及源和目标文件个数的比对,若这三个条件都满足则继续,若一个不满足则写入告警日志并退出。
运行日志截图:
9.告警或通知模块
代码语言:javascript复制#!/bin/bash
DATE=`date -d "20 day ago" %Y-%m-%d`
cd /log/cfs2bos/alter
if [ -s alter.txt ]; then
cat alter.txt | while read line;do echo $line;done
exit 1
else
echo "the files ${DATE} copy sucessed"
exit 2
fi
通过spug平台自定义脚本发出告警或者通知消息
若告警日志为空则发出通知消息'the files ${DATE} copy sucessed',若不为空则发出告警内容。
告警或通知微信截图:
spug平台详见:自动化运维平台Spug测试
六、运行方式
代码语言:javascript复制0 1 * * * /root/cfs2bos.sh >> /log/cfs2bos/cron/cron.txt
本程序采用定时任务方式运行,每天凌晨1点开始。
运行日志截图:
更多shell文章详见:shell脚本专题