• 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;
      }
    
  • 相关阅读:
    配置高并发jdbc连接池
    java中的sleep()和wait()的区别
    程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
    转HashMap Hashtable区别
    chrome 常用快捷操作
    sublime Text 常用操作
    flash 右键菜单隐藏与修改
    As3.0 视频缓冲、下载总结
    flash cs6 更新到Flash player15.0 及Air 更新方法
    As3.0 Interface 与类的使用
  • 原文地址:https://www.cnblogs.com/sunbr/p/13330811.html
Copyright © 2020-2023  润新知