Hadoop 中 FileInputFormat 切片机制 源码分析

FileInputFormat 切片机制源码分析:
用到的源码如下:

FileInputFormat类中的getSplits()方法 

 /** 
   * Generate the list of files and make them into FileSplits.
   */ 
  public List<InputSplit> getSplits(JobContext job
                                    ) throws IOException {
    long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job)); 
    long maxSize = getMaxSplitSize(job); // 默认值是Long类型的最大值

    // generate splits
    List<InputSplit> splits = new ArrayList<InputSplit>();
    List<FileStatus>files = listStatus(job);
    for (FileStatus file: files) {
      Path path = file.getPath();
      FileSystem fs = path.getFileSystem(job.getConfiguration());
      long length = file.getLen();
      BlockLocation[] blkLocations = fs.getFileBlockLocations(file, 0, length);
      if ((length != 0) && isSplitable(job, path)) { 
        long blockSize = file.getBlockSize(); //获取到的是blockSize即block块的大小
        long splitSize = computeSplitSize(blockSize, minSize, maxSize); // 计算splitSize

        long bytesRemaining = length;
        while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
          int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
          splits.add(new FileSplit(path, length-bytesRemaining, splitSize, 
                                   blkLocations[blkIndex].getHosts()));
          bytesRemaining -= splitSize;
        }
        
        if (bytesRemaining != 0) {
          splits.add(new FileSplit(path, length-bytesRemaining, bytesRemaining, 
                     blkLocations[blkLocations.length-1].getHosts()));
        }
      } else if (length != 0) {
        splits.add(new FileSplit(path, 0, length, blkLocations[0].getHosts()));
      } else { 
        //Create empty hosts array for zero length files
        splits.add(new FileSplit(path, 0, length, new String[0]));
      }
    }
    
    // Save the number of input files in the job-conf
    job.getConfiguration().setLong(NUM_INPUT_FILES, files.size());

    LOG.debug("Total # of splits: " + splits.size());
    return splits;
  }

计算splitSize主要用到的是:

protected long computeSplitSize(long blockSize, long minSize,
                                  long maxSize) {
	// 返回的就是block块的大小
    return Math.max(minSize, Math.min(maxSize, blockSize));
  }
long splitSize = computeSplitSize(blockSize, minSize, maxSize);

minSize的计算是:

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

用到以下两个方法:

  protected long getFormatMinSplitSize() {
    return 1;
  }
  public static long getMinSplitSize(JobContext job) {
    return job.getConfiguration().getLong("mapred.min.split.size", 1L);
  }

maxSize的计算是:

long maxSize = getMaxSplitSize(job); // 默认值是Long类型的最大值

用到的方法是:

public static long getMaxSplitSize(JobContext context) {
  return context.getConfiguration().getLong("mapred.max.split.size", 
                                              Long.MAX_VALUE);
  }

那么minSize得到的就是1,maxSize得到的就是Long类型的最大值,最后得到的splitSize的大小就是默认等于blockSize的大小。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Michealkz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值