Java 在Hadoop中更改文件拆分大小

Java 在Hadoop中更改文件拆分大小,java,hadoop,mapreduce,distributed-computing,Java,Hadoop,Mapreduce,Distributed Computing,我在HDFS目录中有一堆小文件。虽然文件量相对较小,但每个文件的处理时间非常长。也就是说,64mb文件(这是TextInputFormat的默认分割大小)甚至需要几个小时才能处理 我需要做的是减小分割大小,这样我就可以利用更多的节点来进行作业 所以问题是,怎样才能按10kb来分割文件?我是否需要为此实现自己的InputFormat和RecordReader,或者是否需要设置任何参数?谢谢 参数mapred.max.split.size可以针对每个作业单独设置,这是您需要的。不要更改dfs.blo

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

我需要做的是减小分割大小,这样我就可以利用更多的节点来进行作业


所以问题是,怎样才能按
10kb
来分割文件?我是否需要为此实现自己的
InputFormat
RecordReader
,或者是否需要设置任何参数?谢谢

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

Hadoop最终指南,第203页“最大拆分大小默认为Java长类型可以表示的最大值。它只有在小于块大小时才有效,强制拆分小于块。 拆分大小通过以下公式计算:

max(minimumSize, min(maximumSize, blockSize))
默认情况下

minimumSize < blockSize < maximumSize
Hadoop在处理少量大文件时比处理大量小文件时效果更好。原因之一是FileInputFormat生成拆分的方式使每个拆分都是单个文件的全部或一部分。如果文件非常小(“小”意味着比HDFS块小得多)它们很多,然后每个映射任务将处理很少的输入,并且会有很多(每个文件一个),每一个都会带来额外的簿记开销。将1gb文件分成16个64mb块和10.000个左右100kb的文件进行比较。10.000个文件每个使用一个映射,作业时间可能比使用单个输入文件和16个映射任务的等效文件慢数十倍或数百倍



编写一个扩展combinefileinputformat的自定义输入格式[在hadoop发行版上有自己的优缺点]。它将输入拆分组合为mapred.max.split.size中指定的值。这里是一个片段,它说明了在没有神奇配置字符串的情况下执行此处所需操作的正确方法。所需常量在
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);

dfs.block.size不一定是全局的;您可以将特定文件的块大小设置为与文件系统的默认块大小不同。我同意mapred.max.split.size可能是这种情况下的解决方法,不过..我还发现对调整输入拆分大小非常有帮助。
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);