【问题标题】:SPARK: Identical stages generated despite cachingSPARK:尽管有缓存,但仍生成相同的阶段
【发布时间】:2019-04-06 22:18:12
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我发现这些 DAG 有时难以解释。我
  • 在持久化之后运行一些操作,如 df.count 或 df.take(n) 并查看阶段是否发生变化。
  • 遗憾的是没有变化。 DAG 看起来一样。
  • 有相同的更新吗?

标签: scala apache-spark apache-spark-sql


【解决方案1】:

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

== 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 中,缓存是急切的,这会对查询性能产生巨大影响,因为您无需调用操作来触发缓存。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-25
    • 2020-07-06
    • 2014-01-08
    • 2018-06-04
    • 2017-09-25
    相关资源
    最近更新 更多