如何知道哪一段代码在驱动程序或执行程序上运行?

Mr *_*ark 24 apache-spark

我是Spark的新手.如何知道哪些代码将在驱动程序上运行以及哪些代码将在执行程序上运行?

我们是否总是必须尝试编码以使所有内容都在执行程序上运行?是否有任何建议/方法可以使您的大部分代码在执行程序上运行?

更新:据我所知,转换器在执行器和操作上运行在驱动程序上运行,因为它需要返回值.如果动作在驱动程序上运行还是应该在执行程序上运行,那么它可以吗?驱动程序实际运行在哪里?在集群?

sep*_*tra 22

任何Spark应用程序都包含一个Driver进程和一个或多个Executor进程.Driver进程将在集群的Master节点上运行,Executor进程在Worker节点上运行.您可以根据使用情况动态增加或减少Executor进程的数量,但驱动程序进程将在应用程序的整个生命周期中存在.

驱动程序进程负责许多事情,包括指导应用程序的整体控制流程,重新启动失败的阶段以及应用程序处理数据的整个高级方向.

对应用程序进行编码以便Executors处理更多数据更多地属于优化应用程序的范围,以便更有效/更快地处理数据,从而利用群集中可用的所有资源.实际上,您并不需要担心确保执行程序正在处理更多数据.

话虽这么说,有一些动作,当触发时,必然涉及到数据的混乱.如果您collect在RDD上调用操作,则所有数据都将被带到驱动程序进程,如果您的RDD中包含足够大量的数据,则Out Of Memory应用程序将触发错误,因为运行驱动程序进程的单个计算机将无法保存所有数据.

牢记上述内容,转换是懒惰的,而动作则不是.转换基本上将一个RDD转换为另一个RDD.但是在RDD上调用转换实际上并不会导致任何数据在任何地方被处理,Driver或Executor.所有的转换都是它添加到DAG的谱系图中,该谱图将在调用Action时执行.

因此,当您在RDD上调用Action时,会发生实际处理.最简单的例子是呼叫collect.一旦调用了一个动作,Spark就会工作并在指定的RDD上执行先前保存的DAG计算,并返回结果.执行这些计算的地方完全取决于您的应用程序.

  • 从HDFS读取,驱动程序将创建一个RDD,其RDD的分区数对应于存储文件的HDFS块的数量.分区将分布在执行程序上.当需要处理数据时,执行程序将读取其特定分区以执行计算. (3认同)

zer*_*323 19

这里没有简单直接的答案.

由于是内部像高阶函数关闭执行拇指一切的规则mapPartitions(map,filter,flatMap),或combineByKey应通过执行大部分机器处理.在这些之外的所有操作都由驾驶员处理.但你必须意识到这是一个严重的简化.

根据特定的方法和语言,驱动程序可以处理至少一部分作业.例如,当您使用combine类似方法(reduce,aggregate)时,最终合并将在驱动程序计算机上本地应用.复杂算法(如许多ML/MLlib工具)可以在需要时交错分布式和本地处理.

而且,数据处理只是整个工作的一小部分.驱动程序负责bookeeping,累加器处理,初始广播和其他辅助任务.它还处理谱系和DAG处理并为更高级别的API生成执行计划(Dataset,SparkSQL).

虽然整个画面在实践中相对复杂,但您的选择相对有限.您可以:

  • 避免收集数据(collect,toLocalIterator)以进行本地处理.
  • 使用tree*(treeAggregate,treeReduce)方法对worker进行更多的工作.
  • 避免不必要的任务,增加簿记费用.