为什么SparkContext.textFile的分区参数不生效?

时间:2015-12-26 00:29:31

标签: scala apache-spark rdd

scala> val p=sc.textFile("file:///c:/_home/so-posts.xml", 8) //i've 8 cores
p: org.apache.spark.rdd.RDD[String] = MapPartitionsRDD[56] at textFile at <console>:21

scala> p.partitions.size
res33: Int = 729

我希望打印8个,我在Spark UI中看到729个任务

编辑:

根据@ zero323

的建议调用repartition()
scala> p1 = p.repartition(8)
scala> p1.partitions.size
res60: Int = 8
scala> p1.count

我仍然在Spark UI中看到729个任务,即使spark-shell打印了8个。

2 个答案:

答案 0 :(得分:7)

如果你看一下签名

textFile(path: String, minPartitions: Int = defaultMinPartitions): RDD[String] 

你会看到你使用的参数被称为minPartitions,这几乎描述了它的功能。在某些情况下,即使这被忽略,但这是另一回事。在幕后使用的输入格式仍决定如何计算分割。

在这种特殊情况下,您可以使用mapred.min.split.size来增加分割大小(这可以在加载期间工作)或加载后只需repartition(这将在加载数据后生效)但通常会有应该没有必要。

答案 1 :(得分:7)

@ zero323对它进行了修改,但我认为我会在此SparkContext.textFile输入参数如何影响分区数量方面添加更多(低级别)背景信息。

tl; dr 分区参数确实会对textFile产生影响,因为最小(不是确切的!)分区数。

在使用SparkContext.textFile的特定情况下,分区数由TextInputFormat使用的org.apache.hadoop.mapred.TextInputFormat.getSplits(jobConf, minPartitions)直接计算。 {{1}} 只有知道如何使用Spark按照建议对分布式数据进行分区(又名 split )。

来自Hadoop&#39; FileInputFormat's javadoc

  

FileInputFormat是所有基于文件的InputFormats的基类。这提供了getSplits(JobConf,int)的通用实现。 FileInputFormat的子类还可以覆盖isSplitable(FileSystem,Path)方法,以确保输入文件不会被拆分并由Mappers作为整体进行处理。

这是Spark利用Hadoop API的一个很好的例子。

顺便说一下,你可能会发现the sources具有启发性; - )