背景:
现项目从外围数据接收到文件通过Flume-ng同步到hdfs上,但Flume只能根据sink配置到指定目录,无法根据文件名生成相应的hdfs目录。
例如: 文件2018070304112301859017101.txt.gz要放到HDFS的路径/home/hadoop/netlog/source/201807/20180703/2018070304下
通过走读代码更改org.apache.flume.sink.hdfs.HDFSEventSink即可。
从CDH网站上下载flume的源码:
下载
地址:http://archive.cloudera.com/cdh5/cdh/5/
可能导入到myeclipse或idel中进行mvn编译下载依赖的包(MVN请自行配置,最好用国内阿里的镜像库,不要把时间浪费在等待上。)
从sink中读取文件写入到HDFS是由process()方法完成。
从上以代码可以看到realPath,realName即是要写入到hdfs的路径及文件名,以下代码也可以验证。
我们只需要更改process中realPath的值即可实现根据文件名realName解析生成路径,以下代码为代码片码:
因为我们要测试所以严格按照日期格式为2018开始后6位全是数字这种格式来做正则匹配。
如果觉得MVN编辑太慢或有些依赖包无法下载,可以采取以下简单办法。
1、新建一个包 包的名字org.apache.flume.sink.hdfs
即HDFSEventSink.java 中包的定义package org.apache.flume.sink.hdfs;
2、在此包下新建class ,名字HDFSEventSink
3、把flume/lib下的jar包全部引入到此工程中,解决代码中的错误
4、对新建的HDFSEventSink进行编译。会在你的工程下面生成相应的class文件
5、把系统中的flume-hdfs-sink-1.6.0-cdh5.14.0.jar用winRAR打开
6、把第四步编译好的HDFSEventSink.class复到flume-hdfs-sink-1.6.0-cdh5.14.0.jar即可,并 上传到flume/lib下。
7、测试在把文件2018070304112301859017101.txt.gz复制到flume配置的源目录中(spooldir中)
8、在hdfs中正常生成文件及目录正常复制到hdfs路径下。
注:更通用的办法是在flume的配置文件中自己定义参数在configure进行取值,根据取的参数进行解码走不同的程序流程,程序片段如下: