首页 > 解决方案 > SPARK:尽管有缓存,但仍生成相同的阶段

问题描述

我想知道我怎么能有两个完全相同的阶段,尽管我在 Spark 中的每个操作之前缓存了我的数据。你能看看下面的截图吗,我觉得它很奇怪。这是否意味着我分阶段执行任务两次?

不幸的是,很难给出代码示例,但我会尝试解释我的工作。

  1. 从 CSV 读取数据
  2. 对特定列进行一些转换。
  3. 应用架构 ->spark.Session.createDataFrame(df.rdd,schema)
  4. 通过在第 3 点创建的 DF 上使用不同的过滤器创建 7 个新数据帧)
  5. 出于比较的原因,从第 4 点获取两个数据帧并将它们传递给另一种方法。

我在第 2 点之后和第 4 点之后坚持只将要比较的两个数据帧。并在比较后不坚持。比较是一个漫长而复杂的过程。

在此处输入图像描述

标签: scalaapache-sparkapache-spark-sql

解决方案


您可以使用 explain 运算符查看 DataFrame 是否缓存在您的物理计划中(其中 InMemoryRelation 实体反映缓存的数据集及其存储级别):

== Physical Plan ==
*Project [id#0L, id#0L AS newId#16L]
+- InMemoryTableScan [id#0L]
      +- InMemoryRelation [id#0L], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas)
            +- *Range (0, 1, step=1, splits=Some(8))

在你缓存(或持久化)你的 DataFrame 之后,第一个查询可能会变慢,但它会为以下查询带来回报。

您可以使用以下代码检查数据集是否已缓存:

scala> :type q2
org.apache.spark.sql.Dataset[org.apache.spark.sql.Row]

val cache = spark.sharedState.cacheManager
scala> cache.lookupCachedData(q2.queryExecution.logical).isDefined
res0: Boolean = false

Spark SQL 中的缓存有一个惊喜。缓存是惰性的,这就是为什么你要付出额外的代价来缓存第一个动作的行,但这只会发生在 DataFrame API 上。在 SQL 中,缓存是急切的,这会对查询性能产生巨大影响,因为您无需调用操作来触发缓存。


推荐阅读