解决Flume采集数据时在HDFS上产生大量小文件的问题

问题:flume指定HDFS类型的Sink时,采集数据至HDFS指定目录,会产生大量小文件。

 

问题重现:

1、创建flume配置文件flume-env.sh,:

解决Flume采集数据时在HDFS上产生大量小文件的问题

flume配置文件如下(根据自身需要修改):

解决Flume采集数据时在HDFS上产生大量小文件的问题

    因为flume可以配置多种采集方式,每种采集方式对应一个agent配置文件,flume即通过运行agent完成采集工作,这里为了方便重现问题,直接监控整个目录。

flume的agent配置文件如下(根据自身需要修改):

解决Flume采集数据时在HDFS上产生大量小文件的问题

解决Flume采集数据时在HDFS上产生大量小文件的问题

 

2、建立待监控目录:

解决Flume采集数据时在HDFS上产生大量小文件的问题

 

3、执行flume的agent

/mnt/disk1/apache-flume-1.7.0-bin/bin/flume-ng agent -n a1 -c /root/flume_conf_jbw -f /root/flume_agent_conf_jbw/a1.conf -Dflume.root.logger=INFO,console

a1为agent的名称
a1.conf为flume配置文件的名称
-c指向log4j.properties文件和flume_env.sh文件所在目录。
--Dflume.root.logger=INFO,console 在终端输出运行日志

 

    可见以采集完成的 文件会加上.COMPLETE后缀,注意,若此时再在监控目录新建同名文件,flume会报错,因为采集完成后会产生相同的文件名的文件。若发生此情况,需要重新运行flume的agent。

解决Flume采集数据时在HDFS上产生大量小文件的问题

    在HDFS目录上查看采集到的数据,内容如下,零散小文件:

解决Flume采集数据时在HDFS上产生大量小文件的问题

 

解决方案:

检查flume配置文件

解决Flume采集数据时在HDFS上产生大量小文件的问题

    

a1.sinks.k1.hdfs.round=true
a1.sinks.k1.hdfs.round=true
a1.sinks.k1.hdfs.round=true,

将以上三行删除,新增如下两行

a1.sinks.k1.hdfs.rollSize=0
a1.sinks.k1.hdfs.rollCount=0

再次重启Flume客户端采集即可。可见不再是小文件了,如下:

解决Flume采集数据时在HDFS上产生大量小文件的问题

 

分析原因:

    Flume可以设置文件

查阅flume配置参数,如下:

rollSize
默认值:1024,当临时文件达到该大小(单位:bytes)时,滚动成目标文件。如果设置成0,则表示不根据临时文件大小来滚动文件。

rollCount
默认值:10,当events数据达到该数量时候,将临时文件滚动成目标文件,如果设置成0,则表示不根据events数据来滚动文件。

round
默认值:false,是否启用时间上的”舍弃”,类似于”四舍五入”,如果启用,则会影响除了%t的其他所有时间表达式;

roundValue
默认值:1,时间上进行“舍弃”的值;

roundUnit

默认值:seconds,时间上进行”舍弃”的单位,包含:second,minute,hour

当设置了round、roundValue、roundUnit参数收,需要在sink指定的HDFS路径上指定按照时间生成的目录的格式,例如有需求,每采集1小时就在HDFS目录上生成一个目录,里面存放这1小时内采集到的数据。

编写sink部分的配置文件如下:

a1.sinks.k1.hdfs.path = hdfs://nameservice1/tmp/flume/jbw/%y-%m-%d/%H%M%S
a1.sinks.k1.hdfs.round = true
a1.sinks.k1.hdfs.roundValue = 60
a1.sinks.k1.hdfs.roundUnit = minute

当时间为2018-6-7 17:38:59时候,hdfs.path依然会被解析为:

/flume/events/20151016/17:30/00
因为设置的是舍弃10分钟内的时间,因此,该目录每10分钟新生成一个。

此时,若当时间为2018-6-7 10:00:00时候,hdfs.path会被解析为:

hdfs://nameservice1/tmp/flume/jbw/20180607/10:00:00

在时间为2018-6-7 10:59:59时候,hdfs.path依旧会被解析为:

hdfs://nameservice1/tmp/flume/jbw/20180607/10:00:00

在时间为2018-6-7 11:02:00时候,hdfs.path则会被解析为:

hdfs://nameservice1/tmp/flume/jbw/20180607/11:00:00

本次产生大量小文件的原因就是hdfs.path中没有指定对应的目录日期对应格式(%y-%m-%d/%H%M%S)。

 

解决方案:

去掉round时间系列参数,并将rollSize和rollCount置0,表示不根据临时文件大小和event数量来滚动文件(滚动文件即指将HDFS上生成的以.tmp结尾的临时文件转换为实际存储文件)。当然,也可以调大rollSize参数(如调至100000000,表示100MB滚动文件,单位是bytes)。

 

PS:网上还有另一种出现大量小文件对应的解决方案,即设置a1.sinks.k1.hdfs.minBlockReplicas=1。因为文件会因为所在块的复制而滚动文件。  

上一篇:Oracle之PL/SQL编程_数据类型与定义变量和常量


下一篇:matlab学习(1)strsplit与strtok