我正在学习Spark的CodeGen机制,但对Spark将RDD的转换/动作转换为逻辑计划的方式感到困惑。 Spark应用程序如下:
def sparkTest(): Any = {
val spark = SparkInit.spark
import spark.implicits._
val data = Seq(1, 2, 3, 4, 5, 6, 7, 8)
// closure start
val const = 3
def mulBy(factor: Double) = (x: Double) => factor * x
val mulByval = mulBy(const)
// closure end
val testRDD = data.toDS()
val filterRDD = testRDD.filter(i =>
mulByval(i) <= 7
)
filterRDD.collect()
filterRDD.foreach(i =>
println(i)
)
}
我试图跟踪源代码,但是当代码转到Dataset.collect时,找到了queryExecution。
def collect(): Array[T] = withAction("collect", queryExecution)(collectFromPlan)
queryExecution如下
== Parsed Logical Plan ==
'TypedFilter <function1>, int, [StructField(value,IntegerType,false)], unresolveddeserializer(upcast(getcolumnbyordinal(0, IntegerType), IntegerType, - root class: "scala.Int"))
+- LocalRelation [value#46]
== Analyzed Logical Plan ==
value: int
TypedFilter <function1>, int, [StructField(value,IntegerType,false)], cast(value#46 as int)
+- LocalRelation [value#46]
== Optimized Logical Plan ==
TypedFilter <function1>, int, [StructField(value,IntegerType,false)], value#46: int
+- LocalRelation [value#46]
== Physical Plan ==
*Filter <function1>.apply$mcZI$sp
+- LocalTableScan [value#46]
但我无法找到逻辑计划生成的时间和地点。 有没有我错过的东西?
答案 0 :(得分:1)
这里有一点混淆。 RDD api实际上并没有生成计划。它们作为Datasets利用的原始或旧api存在。在您的特定示例中,当您编写此行时,查询计划开始构建(尽管它是惰性的)。
val testRDD = data.toDS()
在此之后你不再拥有RDD,你有一个DataSet,它是根据&#34; data&#34;的结果编码的。您可以通过调用explain方法查看任何数据集的计划以获取更多详细信息。
总结
更详细地查看您的代码,实际上从未使用过RDD。您从Collection开始,直接转到数据集,该数据集创建一个LocalTableScan,它基本上只是将值转换为InternalRowRepresentation并将它们并行化。有关详细信息,请参阅LocalTableScanExec