玩过大数据的人,肯定都遇到过小文件问题。这也是玩大数据,必须跨过去的一个坎,要不然,大数据玩不转。
一,怎么定义小文件
hadoop1,默认存储64M。hadoop2,hadoop3默认是128M,当然这些都是可调的。那问题来了,多小的文件算小呢,1M,10M,100M?个人认为,应当是以设置的默认存储块为基准来判定。
那么问题又来了:如果默认存储128M,那么100M算小文件吗?120M算小文件吗?
其实这个问题,很难回答,不同的人有不同的回答。个人觉得,小文件的解决是有一个范围值 ,并且是自己设定的范围值,每个人都不一样。从小到大,越是接近默认存储块,小文件解决的就是越好,反之越差。
二,小文件是怎么产生的?
1,hadoop设计之初是为了OLAP用的,后来越来越多的人,希望hadoop能朝着OLTP的方向发展,并产生了很多工具,例如spark,flink等。实时性要求越高,小文件就会越多。当然这也根量也有关系,量越大,小文件越少,小文件问题越小。
2,在离线计算时,如果没有设置reduce tasks,每个reduce都会生成一个独立的文件。这也会导致小文件的增多。
3,直接copy文件到hdfs,而导致的小文件。
三,为什么小文件是问题?
举个例子:
现在有100怀水,每杯水500ml,而给你装水的工具是N多个水桶,每个水桶容量是5L,现在要利用这些桶把水运到另外一个地方去。并且运一桶水消耗的资源根运一杯水消耗的一样。怎么运最节省资源。
这不就是小学的数学应用题吗?只要小学毕业了,就知道怎么去运水。
四,怎么解决小问题
官方给了三个解决方案:
1,Hadoop Archive
2,Sequence File
3,CombineFileInputFormat
而这三个方案,我没有用,关键是不知道,怎么用,哈哈。
我的解决办法:
1,利用hdfs命令,用appendToFile合并文件,或者getmerge合并文件到本地,然后在传hdfs。配合bash操作,还是可行的。该方案局限性较大。
json,txt试过,可以这样合。parquet肯定不行。orc没试,估计也不行。
数据量不大的话,这种处理方案,还是不错。可以做为补漏方案。
2,利用flume。flume从kafka中,消费数据到hdfs中,设置好rollSize和rollInterval,还是一个不错的方案。该方案也是有局限性的,
一般来说flume获取的数据都ETL前的数据,或者说都是源数据。源数据是要清洗的,清洗的过程中,要洗掉多少数据其实是不可控的。
如果量比较小,并且实时性要求比较高的话,这种方案是不合适的。
3,利用hive的分桶表。设置分桶的数量,可以控制小文件的。该方案也有局限性
如果量很大的情况下,为了接近我们设置默认存储值。就要不断的调整分桶数量。
4,通过程序的方式来合并。例如:spark streaming 准实时的生成了很多小文件,我们可以通过每隔一段时间,把新增的数据,进行数据清洗和合并。如果是json,txt格式,还要用appendToFile,进行补漏。
5,利用hbase,小文件交给hbase的mapfile。
推荐,方法4和方法5,这二种办法也是我现在用的方法。
转载请注明
作者:海底苍鹰
地址:http://blog.51yip.com/hadoop/2357.html