执行顺序和缓存需求

时间:2018-05-07 17:12:22

标签: python apache-spark hadoop pyspark bigdata

让我们考虑使用spark这样一段python伪代码。

    rdd1 = sc.textFile("...")
    rdd2 = rdd1.map().groupBy().filter()
    importantValue = rdd2.count()
    rdd3 = rdd1.map(lambda x : x / importantValue)

DAG spark任务中,创建rdd1后有两个分支。两个分支都使用rdd1,但第二个分支(计算rdd3)也使用来自rdd2importantValue)的汇总值。我假设DAG看起来像这样: enter image description here 我对吗?如果是,我们是否可以假设计算rdd1中使用的rdd3仍然在内存中处理?或者我们必须缓存rdd1以防止重复加载?

更一般地说,如果DAG看起来像这样: enter image description here 我们可以假设两个分支都是相似地计算并使用rdd1的相同副本吗?或者Spark驱动程序会一个接一个地计算这些分支,因为这是两个不同的阶段?我知道在执行之前,火花驱动程序会将DAG分成几个阶段和更详细的逻辑部分 - tasks。一个阶段内的任务可以用pararell计算,因为内部没有洗牌阶段,但是图像中的两个pararell分支怎么样?我知道所有的直觉都在思考rdd抽象(lazy evaluetion等),但这并不会让我更容易理解。请给我任何建议。

2 个答案:

答案 0 :(得分:1)

  

我认为DAG看起来像这样:我是对的吗?

  

如果是,我们可以假设计算rdd3中使用的rdd1仍在内存中处理吗?

没有。 Spark利用惰性评估来处理数据。这意味着在需要之前不会计算任何内容。除非有明确的陈述,否则不会存储任何内容。

  

或者我们必须缓存rdd1以防止重复加载?

确切地说,您需要缓存rdd1以防止文本文件被读取两次。

  

更一般地说,如果DAG看起来像这样:我们可以假设两个分支都是相似地计算并使用相同的rdd1副本吗?或者Spark驱动程序会一个接一个地计算这些分支,因为这是两个不同的阶段?

这两个分支将不会并行处理,因为它们具有单独的谱系。通常,在采取措施之前不会处理任何数据。每当需要一个结果(读取,调用一个动作)时,将发生所有进行转换的数据处理和给定沿袭中的当前动作。之后,除非调用cache,否则内存中不会存在任何数据。

有关转换与操作的解释,请参阅此deck

答案 1 :(得分:1)

  

我们可以假设计算rdd3中使用的rdd1仍然在内存中处理吗?或者我们必须缓存rdd1以防止重复加载?

rdd1未缓存。要对其进行缓存,您需要显式缓存它,并确保.cache()返回的RDD存储在用于创建rdd2的变量中:

rdd1 = sc.textFile("...").cache()
rdd2 = rdd1.map().groupBy().filter()

如果要将其添加到您的图表中,rdd1rdd2之间会有另一个RDD。

  

我们可以假设两个分支都是相似地计算并使用相同的rdd1副本吗?或者Spark驱动程序会一个接一个地计算这些分支,因为这是两个不同的阶段?

什么决定了并行运行的工作是不是(分支机构)沿袭,它是工作请求本身。假设你跑了:

rdd4.count()
rdd5.count()

这将执行rdd1 - > rdd2 - > rdd4然后计数,然后 rdd1 - > {{1} } - GT; rdd3。这个计算将是连续的。

要并行运行这两个图,必须并行提交作业(异步调用)。解决这个问题有很多问题。查看thisthis