hadoop文件接口FileInputFormat中split计算方法

在FileInputFormat map操作中有一块非常中的split的算法 ,

以wordcount为例子,他到底是如果做分片的,我们如何来调优呢,

首先我们来看下他的算法:

在FileInputFormat    public List<InputSplit> getSplits(JobContext job)  中计算 分片大小用到的几个数据我么先来看一下:

// 主要以来配置中的 值,缺省为 1 ;

long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));

protected long getFormatMinSplitSize() {
    return 1;
  }

public static long getMinSplitSize(JobContext job) {
    return job.getConfiguration().getLong(SPLIT_MINSIZE, 1L);
  }

public static final String SPLIT_MINSIZE = 
    "mapreduce.input.fileinputformat.split.minsize";

这里  mapreduce.input.fileinputformat.split.minsize 在 /mapred-default.xml 的配置主哦功能默认是 0  ,所以getMinSplitSize 返回缺省值 1 ;

而 getFormatMinSplitSize  返回值 值也是  1;

通过 Max之后 最后得到的值是1 ;

这里 可以配置的 就是 split.minsize  ,所以这个值如果配置的大于1的话 ,那么 minSize  就是  配置主哦功能的split.minsize了,

//默认使用最大值,配置了,就使用配置的值;

long maxSize = getMaxSplitSize(job);

public static long getMaxSplitSize(JobContext context) {
    return context.getConfiguration().getLong(SPLIT_MAXSIZE, 
                                              Long.MAX_VALUE);
  }

 public static final String SPLIT_MAXSIZE = 
    "mapreduce.input.fileinputformat.split.maxsize";

 从代码可以看出来,缺省使用了 Long.MAX_VALUE,如果配置就是用 配置的值,

// 在配置文件 file.blocksize  core-default.xml 默认值 给的 64*1024*1024

long blockSize = file.getBlockSize();

long splitSize = computeSplitSize(blockSize, minSize, maxSize);

  protected long computeSplitSize(long blockSize, long minSize,
                                  long maxSize) {
    return Math.max(minSize, Math.min(maxSize, blockSize));
  }

 实际上是取出了  在 block中splitMax中取出一个最小值,在和分块最小值中取出 较大的一个,

举个例子:

 加入 wordcount中使用 最小分块 为 3  ,最大分块为 10,blocksize 为默认 67108864

,那么最终结果为  是 10 

但是我们在跑wordcount的时候,我们应该是都没有 设置这写参数,那么应该都是默认值:

minSize:1    maxSize:Long.MAX_VALUE-- 9223372036854775807   blocksize:67108864

最终得到的值即:blocksize:67108864

那么在 wordcount 如果出现块的大小刚好把一个单词截断了怎么办呢?

待续.............

这个配置项定义了在HDFS上每个block的大小,它的值是以字节为单位。

可以在配置文件hadoop-site.xml(Hadoop 0.20 以前版本)定义,

也可以在JobConf里定义。hdfs中block size定义是以文件为粒度的。

 hadoop的mapper数基本由输入文件的block数决定,如果输入的block

size不够大,导致mapper处理时间很短(不到一分钟),大量这样的mapper

会严重降低计算性能。但是如果输入文件都是小文件,就算blocksize再大,每个

文件也会占一个block,这时候要通过合并小文件来减少mapper数,设置blocksize

是没用的。命令行设置块大小可以加参数,0.20以后的用

hadoop fs -D dfs.block.size=134217728 -put local_name remote_location

之前的可以用fs.local.block.size 参数

新版在 dfs.blocksize中设置

 

猜你喜欢

转载自younglibin.iteye.com/blog/1929255