zoukankan      html  css  js  c++  java
  • MapReduce之 FileInputFormat的切片策略(默认)

    • ①获取当前输入目录中所有的文件
    • ②以文件为单位切片,如果文件为空文件,默认创建一个空的切片
    • ③如果文件不为空,尝试判断文件是否可切(不是压缩文件,都可切)
    • ④如果文件不可切,整个文件作为1片
    • ⑤如果文件可切,先获取片大小(默认等于块大小),循环判断 待切部分/ 片大小 > 1.1,如果大于先切去一片,再判断…
    • ⑥剩余部分整个作为1片

    以下为源码部分

    public List<InputSplit> getSplits(JobContext job) throws IOException {
    StopWatch sw = new StopWatch().start();
    // minSize从mapreduce.input.fileinputformat.split.minsize和1之间对比,取最大值
    long minSize = Math.max(getFormatMinSplitSize(), getMinSplitSize(job));
    // 读取mapreduce.input.fileinputformat.split.maxsize,如果没有设置使用Long.MaxValue作为默认值
        long maxSize = getMaxSplitSize(job);
    
        // generate splits
    List<InputSplit> splits = new ArrayList<InputSplit>();
    // 获取当前Job输入目录中所有文件的状态(元数据)
    List<FileStatus> files = listStatus(job);
    // 以文件为单位进行切片
        for (FileStatus file: files) {
          Path path = file.getPath();
          long length = file.getLen();
          if (length != 0) {
            BlockLocation[] blkLocations;
            if (file instanceof LocatedFileStatus) {
              blkLocations = ((LocatedFileStatus) file).getBlockLocations();
            } else {
              FileSystem fs = path.getFileSystem(job.getConfiguration());
              blkLocations = fs.getFileBlockLocations(file, 0, length);
            }
          // 判断当前文件是否可切,如果可切,切片
            if (isSplitable(job, path)) {
              long blockSize = file.getBlockSize();
              long splitSize = computeSplitSize(blockSize, minSize, maxSize);
               // 声明待切部分数据的余量
              long bytesRemaining = length;
    // 如果 待切部分 / 片大小  > 1.1,先切去一片,再判断
              while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
                int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
                splits.add(makeSplit(path, length-bytesRemaining, splitSize,
                            blkLocations[blkIndex].getHosts(),
                            blkLocations[blkIndex].getCachedHosts()));
                bytesRemaining -= splitSize;
              }
    // 否则,将剩余部分整个作为1片。 最后一片有可能超过片大小,但是不超过其1.1倍
              if (bytesRemaining != 0) {
                int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining);
                splits.add(makeSplit(path, length-bytesRemaining, bytesRemaining,
                           blkLocations[blkIndex].getHosts(),
                           blkLocations[blkIndex].getCachedHosts()));
              }
            } else { // not splitable
             // 如果不可切,整个文件作为1片!
              splits.add(makeSplit(path, 0, length, blkLocations[0].getHosts(),
                          blkLocations[0].getCachedHosts()));
            }
          } else { 
            //Create empty hosts array for zero length files
    // 如果文件是个空文件,创建一个切片对象,这个切片从当前文件的0offset起,向后读取0个字节
            splits.add(makeSplit(path, 0, length, new String[0]));
          }
        }
        // Save the number of input files for metrics/loadgen
        job.getConfiguration().setLong(NUM_INPUT_FILES, files.size());
        sw.stop();
        if (LOG.isDebugEnabled()) {
          LOG.debug("Total # of splits generated by getSplits: " + splits.size()
              + ", TimeTaken: " + sw.now(TimeUnit.MILLISECONDS));
        }
        return splits;
      }
    
  • 相关阅读:
    系统兼容性与软件兼容性
    SqlServer 笔记三 规则
    Sql Server 2008 与 Visual Studio 2008 安装说明
    Ms Sql Server
    Git系列教程三 配置与基本命令
    Git系列教程一 入门与简介
    Git系列教程二 基础介绍
    浏览器IE与非IE区分
    SqlServer 笔记二 获取汉字的拼音首字母
    时间戳与日期字符串的转换
  • 原文地址:https://www.cnblogs.com/sunbr/p/13330811.html
Copyright © 2011-2022 走看看