在Hadoop中更改文件分割大小

我在HDFS目录中有一堆小文件。 虽然文件量相对较小, 但每个文件的处理时间量很大 。 也就是说, 64mb文件是TextInputFormat的默认分割大小,甚至需要几个小时才能处理。

我需要做的是减少分割大小 ,这样我就可以利用更多的节点来完成工作。

所以问题是,怎么可以分开文件让我们说10kb ? 我需要为此实现自己的InputFormatRecordReader ,还是要设置任何参数? 谢谢。

您可以单独为每个作业设置参数mapred.max.split.size 。 不要更改dfs.block.size因为这对于HDFS来说是全局的,并且可能导致问题。

Hadoop权威指南,第203页“最大分割大小默认为Java长类型可以表示的最大值。仅当它小于块大小时才有效, 强制分割小于块 。分割大小由公式计算:

 max(minimumSize, min(maximumSize, blockSize)) 

默认

 minimumSize < blockSize < maximumSize 

所以拆分大小是blockSize

例如,

 Minimum Split Size 1 Maximum Split Size 32mb Block Size 64mb Split Size 32mb 

Hadoop使用少量大文件比使用大量小文件更好。 其中一个原因是FileInputFormat以这样一种方式生成拆分,即每个拆分都是单个文件的全部或部分。 如果文件非常小(“小”意味着比HDFS块小得多)并且有很多文件,那么每个地图任务将处理很少的输入,并且会有很多(每个文件一个),每个都会增加额外的簿记费用。 比较一个分成16个64mb块的1gb文件和10.000个左右的100kb文件。 10.000文件每个使用一个映射,并且作业时间可能比具有单个输入文件和16个映射任务的等效文件慢几十或几百倍。


这是片段,它说明了在没有魔术配置字符串的情况下执行所需操作的正确方法。 需要的常量在FileInputFormat定义。 如果需要,可以从默认HDFS块常量中获取块大小,但用户定义的概率非常高。

如果已定义,我只将最大分割大小除以2。

 import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; // .... final long DEFAULT_SPLIT_SIZE = 128 * 1024 * 1024; final Configuration conf = ... // We need to lower input block size by factor of two. conf.setLong( FileInputFormat.SPLIT_MAXSIZE, conf.getLong( FileInputFormat.SPLIT_MAXSIZE, DEFAULT_SPLIT_SIZE) / 2); 

编写一个自定义输入格式,它扩展了combinefileinputformat [有自己的优点,而且还有hadoop发行版]。 它将输入拆分组合为mapred.max.split.size中指定的值

“Hadoop:The Definitive Guide”,p。 202:

给定一组文件,FileInputFormat如何将它们转换为分割? FileInputFormat仅拆分大文件。 这里“大”意味着比HDFS块大。 分割大小通常是HDFS块的大小。

所以你应该改变HDFS块的大小,但这是错误的方法。 也许您应该尝试查看MapReduce应用程序的体系结构。