Spark 源码系列 - textFile -> inputSplit

理解

  • goalSize:每个分区的预估大小(字节)
  • splitSize: 实际分区大小
  • 预估分区大小不足128M, 按照预估大小; 如果超过128M 就是128M

源码


  public InputSplit[] getSplits(JobConf job, int numSplits)
    throws IOException {
    ...
    // 如果是目录listStatus返回目录下的全部文件描述信息,如果是文件,返回文件描述信息
    FileStatus[] stats = listStatus(job);
    ...
    for (FileStatus file: stats) {
      ...
      // 全部文件的字节和
      totalSize += file.getLen();
    }
    // numSplits是参数的值,就是textFile的参数,默认是2. goalSize一般是(全部)文件大小的字节数/2
    long goalSize = totalSize / (numSplits == 0 ? 1 : numSplits);
    // minSplitSize 默认为1,只有在二进制文件SequenceFileInputFormat的处理时候,才会调用setMinSplitSize方法,设置值。
    // SPLIT_MINSIZE (mapreduce.input.fileinputformat.split.minsize)默认为0,
    // minSize默认是1.
    long minSize = Math.max(job.getLong(org.apache.hadoop.mapreduce.lib.input.
      FileInputFormat.SPLIT_MINSIZE, 1), minSplitSize);

    // generate splits
    ArrayList<FileSplit> splits = new ArrayList<FileSplit>(numSplits);
    ...
    // 针对每一个文件
    for (FileStatus file: files) {
        ...
        if (isSplitable(fs, path)) {
          /*
             这里获取的不是文件本身的大小,获取的是HDFS文件块大小
             在HDFS集群模式下,   由 dfs.block.size 决定,Hadoop2.0,默认值是128MB
             在HDFS的local模式下,由 fs.local.block.size 决定,默认值是32MB
           */
          long blockSize = file.getBlockSize();
          // computeSplitSize 核心逻辑 return Math.max(minSize, Math.min(goalSize, blockSize));
          // 如果预估分区大小不足128M, 按照预估大小; 如果超过128M 就是128M; 
          // 也就是分区大小不超过128M,不足128M按照实际大小; 超过128M,分区大小就是128M
          // 如果minSize 特别大(超过实际大小,或者超过128M),就用预设的minSize
          long splitSize = computeSplitSize(goalSize, minSize, blockSize);
          ...
          // 开始切分文件
          while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {
            String[][] splitHosts = getSplitHostsAndCachedHosts(blkLocations,
                length-bytesRemaining, splitSize, clusterMap);
            // makeSplit创建FileSplit对象,该对象存储每个分片的文件路径、读取的offset和length、服务器信息
            splits.add(makeSplit(path, length-bytesRemaining, splitSize,
                splitHosts[0], splitHosts[1]));
            bytesRemaining -= splitSize;
          }
          ...
        ...
    return splits.toArray(new FileSplit[splits.size()]);
  }


参考

https://juejin.cn/post/6844903535889383438

posted @ 2022-05-21 23:42  608088  阅读(114)  评论(0编辑  收藏  举报