如何强制Spark来内联评估DataFrame操作

时间:2016-09-08 00:38:04

标签: apache-spark lazy-evaluation distributed-computing rdd spark-dataframe

根据Spark RDD docs

  

Spark中的所有转换都是懒惰的,因为它们不会立即计算结果......这种设计使Spark能够更有效地运行。

有时我需要对我的数据帧进行某些操作,然后立即。但是因为数据框操作是" 懒惰评估" (按上述方式),当我在代码中编写这些操作时,很少能保证Spark 实际上执行与其余代码内联的操作。例如:

val someDataFrame : DataFrame = getSomehow()
val someOtherDataFrame : DataFrame = getSomehowAlso()
// Do some stuff with 'someDataFrame' and 'someOtherDataFrame'

// Now we need to do a union RIGHT HERE AND NOW, because
// the next few lines of code require the union to have
// already taken place!
val unionDataFrame : DataFrame = someDataFrame.unionAll(someOtherDataFrame)

// Now do some stuff with 'unionDataFrame'...

所以我的解决方法(到目前为止)一直在我的时间敏感数据框操作之后立即运行.show().count(),如下所示:

val someDataFrame : DataFrame = getSomehow()
val someOtherDataFrame : DataFrame = getSomehowAlso()
// Do some stuff with 'someDataFrame' and 'someOtherDataFrame'

val unionDataFrame : DataFrame = someDataFrame.unionAll(someOtherDataFrame)
unionDataFrame.count()  // Forces the union to execute/compute

// Now do some stuff with 'unionDataFrame'...

... 强制 Spark执行数据框操作然后在那里,内联。

对我来说这感觉非常黑客/ kludgy。所以我问:是否有一种更普遍接受和/或有效的方法强制数据帧操作按需发生(而不是懒惰评估)?

2 个答案:

答案 0 :(得分:7)

您必须调用操作以强制Spark执行实际工作。 转换不会触发这种效果,这是爱情的原因之一。

顺便说一句,我很确定非常清楚何时必须完成"就在这里和现在" ,所以你可能正在关注错误的一点。

  

您能否确认count()show()被视为"行动"

您可以在documentation中看到Spark的一些动作功能,其中列出了count()show()不是,我之前没有使用它,但它感觉就像是一个动作 - 如何在不做实际工作的情况下显示结果? :)

  

你是否暗示Spark会自动接收,并做联盟(及时)?

的! :)

会记住您调用的转换,当操作出现时,它会在正确的时间执行它们!

需要记住的事项:由于此政策,仅在出现操作时才进行实际工作,您不会在转换中看到逻辑错误(s ),直到动作发生!

答案 1 :(得分:2)

我同意你的意见,在某些时候你想要在你需要的时候采取行动。 对于.e.g,如果您使用Spark流式传输数据,并且您想要评估在每个RDD上完成的转换,而不是为每个RDD累积转换,并且突然对这大量数据集执行操作。

现在,假设您有一个DataFrame,并且您已对其进行了所有转换,那么您可以使用sparkContext.sql("CACHE table <table-name>")

此缓存是急切缓存,这将触发此DataFrame上的操作,并评估此DataFrame上的所有转换。