Spark在WholeTextFiles上创建的分区少于minPartitions

时间:2018-08-01 08:39:58

标签: apache-spark hdfs yarn distributed-computing partitioning

我有一个包含14个文件的文件夹。我在具有资源管理器纱线的群集上与10个执行程序一起运行spark-submit。

我以此创建第一个RDD:

JavaPairRDD<String,String> files = sc.wholeTextFiles(folderPath.toString(), 10);

但是,files.getNumPartitions()随机给我7或8。然后,我不在任何地方使用合并/分区,而是使用7-8个分区完成DAG。

据我所知,我们以“最小”分区数作为参数,因此Spark为什么将我的RDD划分为7-8个分区?

我还用20个分区运行同一程序,它给了我11个分区。

我在这里看到了一个主题,但这是关于“更多”分区的,根本没有帮助。

注意:在程序中,我读取了另一个包含10个文件的文件夹,Spark成功创建了10个分区。成功完成这项工作后,我进行了上述有问题的转换。

文件大小: 1)25.07 KB 2)46.61 KB 3)126.34 KB 4)158.15 KB 5)169.21 KB 6)16.03 KB 7)67.41 KB 8)60.84 KB 9)70.83 KB 10)87.94 KB 11)99.29 KB 12)120.58 KB 13)170.43 KB 14)183.87 KB

文件位于HDFS上,块大小为128MB,复制因子3。

1 个答案:

答案 0 :(得分:2)

  

如果我们每个文件都有大小,那将更加清楚。但是代码不会错。我正在根据Spark代码库添加此答案

  • 首先, maxSplitSize 的计算取决于 目录大小 最小分区 传入了wholeTextFiles

        def setMinPartitions(context: JobContext, minPartitions: Int) {
          val files = listStatus(context).asScala
          val totalLen = files.map(file => if (file.isDirectory) 0L else file.getLen).sum
          val maxSplitSize = Math.ceil(totalLen * 1.0 /
            (if (minPartitions == 0) 1 else minPartitions)).toLong
          super.setMaxSplitSize(maxSplitSize)
        }
        // file: WholeTextFileInputFormat.scala
    

    link

  • 根据maxSplitSize拆分(Spark中的分区)将从源中提取。

        inputFormat.setMinPartitions(jobContext, minPartitions)
        val rawSplits = inputFormat.getSplits(jobContext).toArray // Here number of splits will be decides
        val result = new Array[Partition](rawSplits.size)
        for (i <- 0 until rawSplits.size) {
          result(i) = new NewHadoopPartition(id, i, rawSplits(i).asInstanceOf[InputSplit with Writable])
        }
        // file: WholeTextFileRDD.scala
    

    link

CombineFileInputFormat#getSplits课上提供了有关读取文件和准备拆分的更多信息。

  

注意:

     

我在这里将 Spark分区称为MapReduce分割,称为Spark   借用了MapReduce的输入和输出格式化程序