(006)Hadoop基础之job的文件split计算法则

Posted sirlijun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(006)Hadoop基础之job的文件split计算法则相关的知识,希望对你有一定的参考价值。

首先我们阅读以下源码,类名是FileInputFormat.class

 public List<InputSplit> getSplits(JobContext job) throws IOException {
        Stopwatch sw = (new Stopwatch()).start();
        long minSize = Math.max(this.getFormatMinSplitSize(), getMinSplitSize(job));
        long maxSize = getMaxSplitSize(job);
        List<InputSplit> splits = new ArrayList();
        List<FileStatus> files = this.listStatus(job);
        Iterator i$ = files.iterator();
        while(true) {
            while(true) {
                while(i$.hasNext()) {
                    FileStatus file = (FileStatus)i$.next();
                    Path path = file.getPath();
                    long length = file.getLen();
                    if (length != 0L) {
                        BlockLocation[] blkLocations;
                        if (file instanceof LocatedFileStatus) {
                            blkLocations = ((LocatedFileStatus)file).getBlockLocations();
                        } else {
                            FileSystem fs = path.getFileSystem(job.getConfiguration());
                            blkLocations = fs.getFileBlockLocations(file, 0L, length);
                        }
                        if (this.isSplitable(job, path)) {
                            long blockSize = file.getBlockSize();
                            long splitSize = this.computeSplitSize(blockSize, minSize, maxSize);

                            long bytesRemaining;
                            int blkIndex;
                            for(bytesRemaining = length; (double)bytesRemaining / (double)splitSize > 1.1D; bytesRemaining -= splitSize) {
                                blkIndex = this.getBlockIndex(blkLocations, length - bytesRemaining);
                                splits.add(this.makeSplit(path, length - bytesRemaining, splitSize, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts()));
                            }
                            if (bytesRemaining != 0L) {
                                blkIndex = this.getBlockIndex(blkLocations, length - bytesRemaining);
                                splits.add(this.makeSplit(path, length - bytesRemaining, bytesRemaining, blkLocations[blkIndex].getHosts(), blkLocations[blkIndex].getCachedHosts()));
                            }
                        } else {
                            splits.add(this.makeSplit(path, 0L, length, blkLocations[0].getHosts(), blkLocations[0].getCachedHosts()));
                        }
                    } else {
                        splits.add(this.makeSplit(path, 0L, length, new String[0]));
                    }
                }
                job.getConfiguration().setLong("mapreduce.input.fileinputformat.numinputfiles", (long)files.size());
                sw.stop();
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Total # of splits generated by getSplits: " + splits.size() + ", TimeTaken: " + sw.elapsedMillis());
                }
                return splits;
            }
        }
    }

根据源代码而知:

max(minSize, min(maxSize,blockSize))

min(maxSize,blockSize)maxSize,blockSize之间的最小值

max(minSize, min())minSize, min()之间的最大值

blockSize=128MB

所以增加切片大小有要调整 min(maxSize,blockSize)maxSize值,减小切片大小调整minSize.

 

hadooop提供了一个设置map个数的参数mapred.map.tasks,我们可以通过这个参数来控制map的个数。但是通过这种方式设置map的个数,并不是每次都有效的。原因是mapred.map.tasks只是一个hadoop的参考数值,最终map的个数,还取决于其他的因素。

 

在设置map个数的时候,可以简单的总结为以下几点:

 

1)如果想增加map个数,则设置mapred.map.tasks 为一个较大的值。

 

2)如果想减小map个数,则设置mapred.min.split.size 为一个较大的值。

 

3)如果输入中有很多小文件,依然想减少map个数,则需要将小文件merger为大文件,然后使用准则2.

 

以上是关于(006)Hadoop基础之job的文件split计算法则的主要内容,如果未能解决你的问题,请参考以下文章

大数据技术之_05_Hadoop学习_04_MapReduce_Hadoop企业优化(重中之重)+HDFS小文件优化方法+MapReduce扩展案例+倒排索引案例(多job串联)+TopN案例+找博客

Hadoop之JobControl管理多个Job

Hadoop中split数量和reader读取原则

hadoop入门之wordcount学习

MapReduce的输入格式

Hadoop中map数的计算