performance - Spark : Explicit caching can interfere with Catalyst optimizer's ability to optimize some queries?

标签 performance apache-spark dataset catalyst

我正在学习使用数据砖来引发认证考试,他们的模拟考试(请参阅 > https://databricks-prod-cloudfront.cloud.databricks.com/public/793177bc53e528530b06c78a4fa0e086/0/6221173/100020/latest.html)要求我们接受以下陈述为真实事实:

"Explicit caching can decrease application performance by interfering with the Catalyst optimizer's ability to optimize some queries"



尽管我已经阅读了很多关于催化剂的内容并且对细节有很好的掌握,但我还是把这个问题弄错了。所以我想巩固我对这个主题的了解,并转到解释这个断言背后的方法和原因的来源。

任何人都可以提供这方面的指导吗?具体来说,为什么会这样?我们如何确保在缓存数据集时实际上不会妨碍优化器并使事情变得更糟?/谢谢!

最佳答案

缓存如何以及为什么会降低性能?

让我们用一个简单的例子来证明:

// Some data
val df = spark.range(100)

df.join(df, Seq("id")).filter('id <20).explain(true)

在这里,催化剂计划将通过在加入之前对每个数据帧进行过滤来优化此加入,以减少将被混洗的数据量。
== Optimized Logical Plan ==
Project [id#0L]
+- Join Inner, (id#0L = id#69L)
   :- Filter (id#0L < 20)
   :  +- Range (0, 100, step=1, splits=Some(4))
   +- Filter (id#69L < 20)
      +- Range (0, 100, step=1, splits=Some(4))

如果我们在加入后缓存查询,查询将不会被优化,正如我们在这里看到的:
df.join(df, Seq("id")).cache.filter('id <20).explain(true)

== Optimized Logical Plan ==
Filter (id#0L < 20)
+- InMemoryRelation [id#0L], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas)
      +- *Project [id#0L]
         +- *BroadcastHashJoin [id#0L], [id#74L], Inner, BuildRight
            :- *Range (0, 100, step=1, splits=4)
            +- BroadcastExchange HashedRelationBroadcastMode(List(input[0, bigint, false]))
               +- *Range (0, 100, step=1, splits=4)

过滤器在最后完成......

为什么这样 ?因为一个 cache将数据帧写入磁盘。因此,每个后续查询都将使用此缓存/写入磁盘 DataFrame 上的数据,因此它将仅优化缓存后的查询部分。我们可以用同样的例子来检查!
df.join(df, Seq("id")).cache.join(df, Seq("id")).filter('id <20).explain(true)

== Optimized Logical Plan ==
Project [id#0L]
+- Join Inner, (id#0L = id#92L)
   :- Filter (id#0L < 20)
   :  +- InMemoryRelation [id#0L], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas)
   :        +- *Project [id#0L]
   :           +- *BroadcastHashJoin [id#0L], [id#74L], Inner, BuildRight
   :              :- *Range (0, 100, step=1, splits=4)
   :              +- BroadcastExchange HashedRelationBroadcastMode(List(input[0, bigint, false]))
   :                 +- *Range (0, 100, step=1, splits=4)
   +- Filter (id#92L < 20)
      +- Range (0, 100, step=1, splits=Some(4))

过滤器在第二次加入之前完成,但在第一个之后完成,因为它被缓存了。

如何避免?

通过知道你做什么!您可以简单地比较催化剂计划并查看 Spark 缺少哪些优化。

关于performance - Spark : Explicit caching can interfere with Catalyst optimizer's ability to optimize some queries?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57369904/

相关文章:

mysql - 有效地存储每个项目的最后 X 条记录

java - Log4j DailyRollingFileAppender 与 ConsoleAppender 性能对比

scala - 从映射中获取列值的值作为 spark 数据帧中的键

datetime - 从 Pyspark 中包含时间戳的字符串列中提取日期

c# - DataSet.Locale 有什么作用?

java - 仅从 Gmail 获取邮件 header

javascript - tumblr 上的慢速查询无限滚动响应?

python - 绘制数据框中所有列的直方图

c# - 如何过滤数据表?

c# - 如何仅将数据库的模式放入数据集中?