如你安好

时间就像海绵里的水,只要愿挤,总还是有的。 -- 鲁迅
如你安好 ,

便是晴天 。

Shell定时采集数据到HDFS

1.编程思路与步骤

为什么会有Shell定时采集数据到HDFS?
服务器每天会产生大量日志数据,并且日志文件可能存在于每个应用程序指定的data目录中,在不使用其它工具的情况下,将服务器中的日志文件规范地存放在HDFS中。通过编写简单的Shell脚本,用于每天自动采集服务器上的日志文件,并将海量的日志上传至HDFS中。
1.png
(该图片来源于网络)
(1)配置环境变量
首先在/export/data/logs目录下(如果目录不存在,则需要提前创建)使用vim命令创建upload_hdfs.sh脚本文件,在编写Shell脚本时,默认使用设置好的Java环境变量和Hadoop环境变量
(2)准备日志存放目录和待上传文件
为了让开发者便于控制上传文件的流程,可以在脚本中设置一个日志存放目录和待上传文件目录,若上传过程中发生错误只需要查看该目录就能知道文件的上传进度。
(3)设置日志文件上传的路径
设置上传的HDFS目标路径,命名格式以时间结尾,并且输出打印信息。
(4)实现文件上传
上传文件的过程就是遍历文件目录的过程,将文件首先移动到待上传目录,再从待上传目录中上传到HDFS中。若是在每天12点凌晨执行一次,我们可以使用Linux Crontab表达式执行定时任务。
那么,准备开始:
创建日志文件存放的目录/export/data/logs/log,执行命令:
创建待上传文件存放的目录/export/data/logs/toupload,执行命令:

[root@master ~]#mkdir -p /export/data/logs/log
[root@master ~]#mkdir -p /export/data/logs/toupload

查看创建的目录树结构,需要使用tree工具,如果没有安装需要安装,输入命令:

[root@master ~]#yum -y install tree

3.jpg
(这个不安装也可以,但是装了更好看文档一些)
(用来查看创建的目录树结构)
准备完毕。

2.编写脚本,实现功能

进入/export/data/logs目录,输入命令:

[root@master ~]#cd /export/data/logs/

编写文件:

[root@master ~]#vi upload_hdfs.sh
#!/bin/bash
# 指定源文件目录和待上传目录
src=/export/data/logs/log/
file_up_load=/export/data/logs/toupload/
# 获取当前日期和时间
date=$(date +%Y_%m_%d)
time=$(date +%Y_%m_%d_%H_%M_%S)
# 指定HDFS根路径
hdfs_root=/data/clickLog/$date/
####################################
# 遍历源文件目录下的所有文件
ls $src | while read -r file
do
    # 判断文件名是否以 "access.log." 开头(可以DIY其他名字)
    if [[ "$file" == access.log.* ]]; then
        # 将源文件移动到待上传目录,并在文件名前添加时间戳
        mv "$src$file" "$file_up_load""lzy_click_log_$file$time"
        # 将移动后的文件路径和名称记录到待上传目录下的日志文件
        echo "$file_up_load""lzy_click_log_$file$time" >> "$file_up_load""willDoing.$date"
    fi
done
####################################
# 遍历待上传目录下的所有文件,过滤出特定名称的文件
ls $file_up_load | grep will | grep -v "_COPY_" | grep -v "_DONE_" | while read -r line1
do
    # 对匹配到的文件进行重命名,添加 "_COPY_" 后缀
    mv "$file_up_load$line1" "$file_up_load$line1""_COPY_"
    # 逐行读取重命名后的文件内容
    cat "$file_up_load$line1""_COPY_" | while read -r line2
    do
        # 在HDFS上创建目标目录(如果不存在),并将文件上传至目标目录
        hdfs dfs -mkdir -p "$hdfs_root"
        hdfs dfs -put "$line2" "$hdfs_root"
    done
    # 对文件进行最终重命名,添加 "_DONE_" 后缀
    mv "$file_up_load$line1""_COPY_"  "$file_up_load$line1""_DONE_"
done

编辑权限,输入命令:

[root@master ~]# chmod 775 upload_hdfs.sh

3,运行脚本,查看结果

为了模拟生产环境,在日志存放目录/export/data/logs/log/中,手动创建日志文件。
access.log表示正在源源不断的产生日志的文件,access.log.1、access.log.2等表示已经滚动完毕的日志文件,即为待上传日志文件。
在upload_hdfs.sh文件路径下运行脚本,先将日志存放目录log中的日志文件移到待上传toupload目录下,并根据业务需求重命名。
然后脚本执行“hdfs dfs -put”上传命令,将待上传目录下的所有日志文件上传至HDFS。
最后通过HDFS WebUI界面可看到需要采集的日志文件已按照日期分类,上传至HDFS中。
创建四个日志文件(必须以access.log.打头),输入下面的命令:

[root@master ~]# echo "hello world" > log/access.log.1
[root@master ~]# echo "hello hadoop" > log/access.log.2
[root@master ~]# echo "hello hdfs" > log/access.log.3
[root@master ~]# echo "hello mapreduce" > log/access.log.4

或者

[root@master ~]# vi log.sh
#!/bin/bash
echo "hello world" > log/access.log.1
echo "hello hadoop" > log/access.log.2
echo "hello hdfs" > log/access.log.3
echo "hello mapreduce" > log/access.log.4

输入命令:

[root@master ~]# ./upload_hdfs.sh

查看/export目录树结构,输入命令:

[root@master ~]# tree /export

1.jpg

4.打开HDFS集群WebUI查看上传的日志文件

2.jpg

5.实现文件上传

上传文件的过程就是遍历文件目录的过程,将文件首先移动到待上传目录,再从待上传目录中上传到HDFS中。若是在每天0点凌晨执行一次,我们可以使用Linux Crontab表达式执行定时任务

[root@master ~]# crontab -e

这会打开一个文本编辑器,用于编辑定时任务列表。
在文本编辑器中输入以下内容:

bash 0 0 *** /path/to/script.sh

其中,“0 0 ***”表示每天零点执行脚本,“/path/to/script.sh”是你编写的Shell脚本路径。

至此,大功告成。

愿望集合地

(仅限登陆用户评论)

这篇文章获得了个赞!