我在Spark应用程序主控制台中查看我的工作,我可以实时查看完成各个阶段,因为Spark在我的应用程序的DAG中占据了一席之地。一切都进展得相当快。有些阶段需要不到一秒钟,有些阶段需要一两分钟。
列表顶部的最后一个阶段是rdd.saveAsTextFile(path, classOf[GzipCodec])
。这个阶段需要很长时间。
我了解转换执行零次,一次或多次,具体取决于因操作而导致的执行计划,例如saveAsTextFile
或{{1 }}。
随着工作的进展,我可以在App Manager中看到执行计划。有些阶段不存在。有些人不止一次出现。这是预料之中的。我可以实时看到每个阶段的进度(只要我一直按F5刷新页面)。执行时间与每个阶段的数据输入大小大致相当。因此,我确定App Manager向我展示的是实际转换的进度,而不是DAG上的某些元活动。
因此,如果在每个阶段都发生了转换,为什么最后阶段 - 从EMR简单地写入S3 - 这么慢?
如果像我的同事建议的那样,应用管理器中显示的转换阶段不正在进行实际计算,那么他们正在做什么消耗如此多的内存,CPU和CPU。时间?
答案 0 :(得分:4)
在Spark中,懒惰评估是一个关键概念,如果你想使用Spark,你最好熟悉这个概念。
您见证完成得太快的阶段不会进行任何重大计算。
If they are not doing actual computation, what are they doing?
他们正在更新DAG。
当一个动作被触发时,Spark有机会咨询DAG以优化计算(在没有延迟优化的情况下这是不可能的。)
如需了解更多信息,请阅读Spark Transformation - Why its lazy and what is the advantage?
而且,我想你的同事急忙给你答案,并错误地说:
transformation are cheap
事实在于ref's RDD operations:
Spark中的所有转换都是惰性的,因为它们不会计算 他们的结果马上。相反,他们只记得 应用于某些基础数据集(例如文件)的转换。该 转换仅在动作需要结果时计算 被送回司机程序。
便宜不是正确的词。
这解释了为什么,在一天结束时,你的最后阶段(实际上要求数据并触发动作)与其他任务相比是如此缓慢。
我的意思是你提到的每个阶段似乎都没有引发任何行动。因此,最后阶段必须考虑所有前期阶段,并完成所需的所有工作,但请记住,在优化的Spark视点中。
答案 1 :(得分:3)
我猜真正的困惑在于:
转型很便宜
变换是懒惰的(大部分时间),但远不及便宜。这意味着转化不会被应用,除非有一个渴望的后代(行动)取决于它。它并没有告诉你任何有关它成本的信息。
一般来说,转型是实际工作发生的地方。与转换中执行的逻辑相比,输出操作(不包括存储/网络IO)通常比较便宜。