版本:Spark 1.6.2,Scala 2.10
我在spark-shell
中执行以下命令。
我试图查看Spark默认创建的分区数。
val rdd1 = sc.parallelize(1 to 10)
println(rdd1.getNumPartitions) // ==> Result is 4
//Creating rdd for the local file test1.txt. It is not HDFS.
//File content is just one word "Hello"
val rdd2 = sc.textFile("C:/test1.txt")
println(rdd2.getNumPartitions) // ==> Result is 2
根据Apache Spark documentation,spark.default.parallelism
是笔记本电脑中的核心数(2核心处理器)。
我的问题是:rdd2
似乎正在提供2个分区的正确结果,如文档中所述。但为什么rdd1
将结果作为4个分区?
答案 0 :(得分:21)
最小分区数实际上是SparkContext
设置的下限。由于 spark 使用 hadoop ,Hadoop InputFormat`默认仍然是行为。
第一种情况应该反映defaultParallelism
所提及的here,这可能会有所不同,具体取决于设置和硬件。 (核心数量等)
因此,除非您提供切片数量,否则第一种情况将由sc.defaultParallelism
描述的数字定义:
scala> sc.defaultParallelism
res0: Int = 6
scala> sc.parallelize(1 to 100).partitions.size
res1: Int = 6
对于第二种情况,sc.textFile
,默认情况下,切片数是最小分区数。
在this section of code中可以看到等于2 。
因此,您应该考虑以下因素:
sc.parallelize
将numSlices
或defaultParallelism
。
sc.textFile
将在minPartitions
和基于hadoop输入分割大小除以块大小计算的分割数之间取最大值。
sc.textFile
调用sc.hadoopFile
,创建一个HadoopRDD
,在引擎盖下使用InputFormat.getSplits
[参考资料。 InputFormat documentation]。
InputSplit[] getSplits(JobConf job, int numSplits) throws IOException
:逻辑分割作业的输入文件集。 然后将每个InputSplit分配给单个Mapper进行处理。 注意:拆分是输入的逻辑拆分,输入文件不会物理拆分为块。对于例如分裂可能是元组。参数:作业 - 作业配置。 numSplits - 所需的分割数,一个提示。返回:作业的InputSplits数组。抛出:IOException。
示例:强>
让我们创建一些虚拟文本文件:
fallocate -l 241m bigfile.txt
fallocate -l 4G hugefile.txt
这将分别创建大小为241MB和4GB的2个文件。
我们可以看到当我们阅读每个文件时会发生什么:
scala> val rdd = sc.textFile("bigfile.txt")
// rdd: org.apache.spark.rdd.RDD[String] = bigfile.txt MapPartitionsRDD[1] at textFile at <console>:27
scala> rdd.getNumPartitions
// res0: Int = 8
scala> val rdd2 = sc.textFile("hugefile.txt")
// rdd2: org.apache.spark.rdd.RDD[String] = hugefile.txt MapPartitionsRDD[3] at textFile at <console>:27
scala> rdd2.getNumPartitions
// res1: Int = 128
它们都是HadoopRDD
s:
scala> rdd.toDebugString
// res2: String =
// (8) bigfile.txt MapPartitionsRDD[1] at textFile at <console>:27 []
// | bigfile.txt HadoopRDD[0] at textFile at <console>:27 []
scala> rdd2.toDebugString
// res3: String =
// (128) hugefile.txt MapPartitionsRDD[3] at textFile at <console>:27 []
// | hugefile.txt HadoopRDD[2] at textFile at <console>:27 []