我们正在执行一些测试来评估Spark with Spark SQL中的转换和操作的行为。在我们的测试中,首先我们设想一个简单的数据流,包含2个转换和1个动作:
LOAD (result: df_1) > SELECT ALL FROM df_1 (result: df_2) > COUNT(df_2)
第一个数据流的执行时间是10秒。接下来,我们在数据流中添加了另一个操作:
LOAD (result: df_1) > SELECT ALL FROM df_1 (result: df_2) > COUNT(df_2) > COUNT(df_2)
分析数据流的第二个版本,因为所有转换都是惰性的并且为每个动作重新执行(根据文档),当执行第二个计数时,它应该要求执行前两个转换(LOAD和SELECT)所有)。因此,我们期望在执行第二版数据流时,时间大约为20秒。但是,执行时间是11秒。显然,第一次计数所需的转换结果被Spark缓存为第二次计数。
拜托,你们知道发生了什么吗?
答案 0 :(得分:1)
看看你的工作,你可能会看到跳过的阶段,这是一件好事。 Spark认识到它仍然具有上一个作业的shuffle输出,并将重用它而不是从源数据开始并重新整理整个数据集。
答案 1 :(得分:0)
Spark DAG调度程序在从Action获取数据后重新定义数据的未来使用.Spark程序隐式创建操作的逻辑有向非循环图(DAG)。当驱动程序运行时,它会转换此逻辑将图表转换为物理执行计划。
当你在RDD上调用一个动作时,它必须被计算出来。在你的情况下,你只是在做一个动作,之后再做一个动作。这也需要计算其父RDD。 Spark的调度程序提交作业以计算所有需要的RDD。这项工作将有一个或多个阶段,这是由任务组成的并行计算波。每个阶段将对应于DAG中的一个或多个RDD。由于流水线操作,单个阶段可以对应多个RDD。