在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中设置