Spark:阶段边界上的磁盘I/O解释



我在官方文档中找不到关于磁盘上Spark临时数据持久性的信息,只有一些Spark优化文章,比如:

在每个阶段边界,父级中的任务将数据写入磁盘阶段,然后由子阶段中的任务通过网络获取。因为它们会导致大量的磁盘和网络I/O,所以阶段边界可能是昂贵且应尽可能避免。

在每个阶段边界上对磁盘的持久性是否总是同时应用于HashJoin和SortMergeJoin?为什么Spark(内存引擎(在shuffle之前对tmp文件进行持久化?这样做是为了任务级别的恢复还是其他什么

p.S.问题主要涉及Spark SQL API,同时我也对Streaming&结构化流

UPD:在"使用Apache Spark进行流处理"一书中发现了关于为什么会发生这种情况的提及和更多细节。在参考页面上查找"任务故障恢复"one_answers"阶段故障恢复"主题。据我所知,Why=recovery,When=always,因为这是负责数据传输的Spark Core和Shuffle Service的机制。此外,所有Spark的API(SQL、Streaming和Structured Streaming(都基于相同的故障转移保证(Spark Core/RDD(。因此,我认为这是Spark在一般中的常见行为

这是一个很好的问题,因为我们听说过内存中的Spark与Hadoop,所以有点令人困惑。这些文件很糟糕,但我做了一些事情,并通过四处寻找最优秀的来源来验证观察结果:http://hydronitrogen.com/apache-spark-shuffles-explained-in-depth.html

假设已经调用了Action,以避免出现明显的评论,如果没有说明这一点,假设我们谈论的不是ResultStage和广播加入,那么我们谈论的是ShuffleMapStage。我们首先来看RDD。

然后,借用网址:

  • 涉及shuffle的DAG依赖意味着创建一个单独的Stage
  • Map操作之后是Reduce操作和Map,依此类推

当前阶段

  • 所有(融合的(Map操作都在Stage内执行
  • 下一个阶段的要求是Reduce操作,例如reduceByKey,这意味着输出按Map末尾的键(K(进行散列或排序当前阶段的操作
  • 这些分组数据被写入执行器所在的Worker上的磁盘,或与该云版本绑定的存储。(我会的如果数据很小,在内存中思考是可能的,但这是一个体系结构Spark文件中所述的方法。(
  • ShuffleManager会收到通知,散列映射数据可供下一阶段使用。ShuffleManager跟踪所有一旦完成了所有的地图侧工作,就可以使用键/位置

下一阶段

  • 下一阶段是reduce,然后通过咨询Shuffle Manager并使用Block Manager从这些位置获取数据
  • 执行者可以被重复使用,也可以是另一个Worker上的新执行者,或者是同一Worker的另一个执行者

所以,我的理解是,从架构上讲,阶段意味着写入磁盘,即使有足够的内存。给定Worker的有限资源,为这种类型的操作写入磁盘是有道理的。当然,更重要的一点是"Map Reduce"的实现。我总结了这篇优秀的帖子,这是你的规范来源。

当然,容错有助于这种持久性,较少的重新计算工作。

类似的方面也适用于DF。

Spark不是,也从来不是"内存引擎"。如果检查内部,很明显,它既没有针对内存内处理进行优化,也没有针对以内存为中心的硬件进行调优。

相反,几乎所有的设计决策都是在假设数据的整体大小以及单个任务的输入和输出可以分别超过集群和单个执行器/执行器线程的可用内存量的情况下做出的。此外,它被明确设计用于商品硬件。

这样的实现可以用于恢复或避免重新计算(例如,请参阅Apache Spark web UI中的"阶段跳过"是什么意思?(,但这是重新调整用途,而不是最初的目标。

最新更新