案例:shell定时采集数据至HDFS
上线的网站每天都会产生日志数据, 假如有这样一个需求, 要求凌晨24点操作前一天产生的日志数据, 准时上传至HDFS集群中。
如何实现?实现后能否实现周期性上传数据?如何定时?
分析:
HDFS SHELL:
hadoop fs -put //上传文件
Linux crontab:
crontab -e 0 0 *** /shell/uploadFile2Hdfs.sh //每天凌晨12点执行一次
实现流程
一般日志文件生成的逻辑有业务系统决定, 比如每小时滚动一次, 或者一定大小滚动一次, 避免当个日志文件过大不方便操作。
比如滚动后的文件,命名为access.log.x,其中x为数字。 正在进行写的日志文件叫做access.log。这样的话, 如果日志文件后缀是 1/ 2 /3等数字, 则该文件满足需求可以上传, 就把该文件移动到准备上传的工作区间目录。工作区间目录有文件之后可以使用hadoop fs -put命令将文件上传。
shell代码
export JAVA_HOME=/root/java/jdk1.8.0_251
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:{JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/lib:$PATH
export HADOOP_HOME=/home/David_Wolfowitz/Hadoop/hadoop-3.2.1
export PATH=${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
#日志文件存放的目录
log_src_dir=/root/logs/log/
#带上传文件存放的目录
log_toupload_dir=/root/logs/toupload/
#日志文件上传到hdfs的根目录
datel=`date -d last-day +%Y_%m_%d`
hdfs_root_dir=/data/clickLog/$datel/
#打印环境变量
echo "env: hadoop_home: $HADOOP_HOME"
# 读取日志文件的目录, 判断是否有需要上传的文件
echo "log_src_dir: $log_src_dir"
ls $log_src_dir | while read fileName
do
#echo "hello"
if [[ "$fileName" == access.log.* ]]; then
date=`date + %Y_%m_%d_%H_%M_%S`
echo "moving $log_src_dir$fileName to $log_toupload_dir"xxxxx_click_log_$fileName"$date"
mv $log_src_dir$fileName $log_toupload_dir"xxxxx_click_log_$fileName"$date
echo $log_toupload_dir"xxxxx_click_log_$fileName"$date >> $log_toupload_dir"willDoing."$date
fi
done
ls $log_toupload_dir | grep will | grep -v "_COPY_" | grep -v "_DONE_" | while read line
do
#echo 'hello'
echo "toupload is in file:"$line
mv $log_toupload_dir$line $log_toupload_dir$line"_COPY_"
cat $log_toupload_dir$line"_COPY_" | while read line
do
echo "puting ... $line to hdfs path ...$hdfs_root_dir"
hadoop fs -mkdir -p $hdfs_root_dir
hadoop fs -put $line $hdfs_root_dir
done
mv $log_toupload_dir$line"_COPY_" $log_toupload_dir$line"_DONE_"
done
参考资料:
【1】 腾讯课堂-大数据hadoop入门