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



我是Spark的新手。如何知道哪段代码将在驱动程序&遗嘱执行人将承担哪些责任?

我们是否总是要尝试编写代码,使所有内容都在执行器上运行?。有什么建议/方法可以让你的大部分代码在执行器上运行吗?

更新:据我所知,转换运行在执行器&操作在驱动程序上运行,因为它需要返回值。所以,如果操作在驱动程序上运行,或者也应该在执行器上运行,这可以吗?驾驶员实际在哪里跑步?在集群上?

任何Spark应用程序都由一个驱动程序进程和一个或多个执行程序进程组成。驱动程序进程将在集群的主节点上运行,执行程序进程在工作节点上运行。您可以根据使用情况动态增加或减少Executor进程的数量,但驱动程序进程将在应用程序的整个生命周期中存在。

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

对应用程序进行编码,以便执行器处理更多的数据,这更符合优化应用程序的权限,以便它能够更高效/更快地处理数据,从而利用集群中所有可用的资源。在实践中,您实际上不需要担心确保执行器正在处理更多的数据。

也就是说,有一些操作,当被触发时,必然涉及数据的混乱。如果对RDD调用collect操作,则所有数据都会被带到Driver进程中,如果RDD中有足够多的数据,则应用程序将触发Out Of Memory错误,因为运行Driver进程的单机将无法保存所有数据。

记住以上几点,转换是懒惰的,而行动不是。转换基本上将一个RDD转换为另一个。但是,在RDD上调用转换实际上不会导致在任何地方处理任何数据,无论是驱动程序还是执行程序。转换所做的只是将其添加到DAG的沿袭图中,该沿袭图将在调用Action时执行。

因此,实际处理发生在您对RDD调用Action时。最简单的例子是调用collect。一旦调用了一个操作,Spark就开始工作,并在指定的RDD上执行以前保存的DAG计算,返回结果。在哪里执行这些计算完全取决于您的应用程序。

这里没有简单明了的答案。

根据经验,在mapPartitionsmapfilterflatMap)或combineByKey等高阶函数的闭包中执行的所有内容都应该主要由执行器机器处理。除此之外的一切都由司机处理。但你必须意识到,这是一个严重的简化。

根据特定的方法和语言,至少有一部分作业可以由驾驶员处理。例如,当您使用类似combine的方法(reduceaggregate)时,最终合并将在驱动程序机器上本地应用。复杂的算法(像许多can-ML/MLlib工具一样)可以在需要时交织分布式和本地处理。

此外,数据处理只是整个工作的一小部分。司机负责记账、累加器处理、初始广播和其他次要任务。它还处理沿袭和DAG处理,并为更高级别的API(DatasetSparkSQL)生成执行计划。

虽然整体情况在实践中相对复杂,但你的选择相对有限。您可以:

  • 避免收集要在本地处理的数据(collecttoLocalIterator
  • tree*treeAggregatetreeReduce)方法对工人进行更多的工作
  • 避免不必要的增加记账成本的任务

对于您问题的这一部分"更新:据我所知,转换是在执行器上运行的&操作在驱动程序上运行,因为它需要返回值"

不是只有转换在执行器上运行,所有操作都在驱动程序上运行。

如果我们必须加入2个不需要执行聚合操作的数据集,例如:

dataset1.join(dataset2,dataset1.col("colA").equalTo(dataset2.col("colA)),
                "left_semi").as(Encoders.bean(Some.class)).write("/user/datasetresult");

在这种情况下,一旦执行器机器完成了对其分区的工作,它就开始将结果写入HDFS/某个持久性,而无需等待其他执行器完成。这就是为什么我们看到不同的部分文件的原因,从技术上讲,这些文件是每个执行器处理的分区。驱动程序不等待所有执行程序完成其计算。

驾驶员实际在哪里跑步?在集群上

取决于所选的--deploy模式。如果是部署模式客户端,那么启动spark应用程序的网关就是驱动程序机器。如果--deploymode集群,集群管理器会选择一台它认为有足够内存作为驱动程序运行的机器(在yars/mesos中)。

最新更新