2015-07-12 93 views
5

RDD通过对象中用户定义的函数/方法进行一系列转换。这些功能以任务的形式传递给执行者。 这些任务是在spark-core中定义的Scala类的实例。spark驱动程序如何序列化发送给执行程序的任务?

我假设用户定义的函数/方法被包装在一个任务对象中并传递给执行者。

  1. 如何执行人知道的是,需要执行 它被包裹在任务类中的方法?

  2. 序列化到底有多有用?

  3. 火花上下文如何读取用户代码并将其转换为任务?

回答

0

一点解释:

如何执行者知道什么是需要被包裹在任务类要执行的方法是什么?

执行人收到任务描述一个RPC味精,见下文

究竟是怎样的序列化有帮助吗?

是,该任务包含由一个closureSerializer

连载怎样火花背景读取用户代码,并将其转换为任务的代码?

在REPL envirenment,火花编译用户代码的类文件,并把文件服务器上,执行器实现了一个自定义的类加载器,其装载从驾驶员侧的文件服务器的类;该类实际上是一个针对记录迭代器运行的函数

3

从根本上通过的Spark函数基于Java Serialization。在Java中,您可以通过网络将任意代码传递给其他机器,可以是简单的案例类或具有任何行为的任何类。

只有一个需求 - 序列化类需要位于目标JVM的类路径中。

在启动时,当您使用​​它的jar文件分发到所有Spark工作节点,它可以让驾驶者序列化功能传递给工作节点,因为序列化类是在类路径可以反序列化,从驱动程序发送的任何功能。

Spark没有为RDD转换定义任何特定的Task类。如果您使用Scala的map操作,则会发送scala Function1的序列化版本。

如果您通过密钥等使用聚合/减少,它可以是Function2。无论如何,这不是Spark特有的,它只是普通的Scala(Java)类。

5

关于spark如何读取用户代码并将其转换为任务?

驱动程序代码生成作业,阶段和任务。

整个驱动程序代码可以作为一个应用程序调用,每个动作构成一个工作。

作业提交给驱动程序时,作业分为逻辑计划和物理计划。

在逻辑计划中,转换()会在一系列RDD中建立计算。 由于每个动作()都会触发一个作业,因此在物理计划期间,转换的完整依赖关系图将分成多个阶段。与hadoop不同,hadoop的执行过程是固定的map-shuffle-sort-aggregate,spark没有固定的执行过程。数据在实际需要时以流动方式计算。它从RDD的最终结果开始,并向后检查RDD链,以找出计算最终结果所需的RDD和分区。在回溯期间,如果它遇到ShuffleDependency,它会切断数据流并形成一个新的阶段,通过NarrowDepedency离开RDD的通道。所以它打破了一个新阶段的ShuffleDependency。

在每个阶段中,执行任务并通过转换对数据进行流水线处理。任务的数量相当于每个阶段的RDD中的分区数量。

所有任务都打包在TaskSet中并发送到TaskScheduler。Driver actor将序列化的任务发送到工作者节点上的CoarseGrainedExecutorBackend Actor。执行者收到后,将其反序列化为正常任务并运行以获得结果。 TaskScheduler将被通知任务已完成,其结果将被处理

如果接收到的驱动程序任务是该阶段中的最后一项任务,则会提交下一个阶段。如果舞台已经是最后一个舞台,dagScheduler会被告知该作业已完成。

从Spark 1.4版本开始,Spark UI中添加了新的可视化。我们可以在哪里看到不同阶段的DAG可视化。