在Hadoop中更改文件分割大小

问题描述 投票:23回答:5

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

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

所以问题是,如何通过让我们说10kb来分割文件?我需要为此实现我自己的InputFormatRecordReader,还是有任何参数要设置?谢谢。

java hadoop mapreduce distributed-computing
5个回答
33
投票

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


22
投票

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个映射任务的等效文件慢几十或几百倍。



3
投票

这是片段,它说明了在没有魔术配置字符串的情况下执行所需操作的正确方法。需要的常数在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);

1
投票

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


-1
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.