RDD通过对象中的用户定义函数/方法进行一系列转换。并且这些函数以任务的形式传递给执行程序。 这些任务是spark-core中定义的Scala类的实例。
我假设用户定义的函数/方法包装在一个任务对象中并传递给执行程序。
执行者如何知道需要的方法是什么 执行哪个包装在任务类中?
序列化到底有何帮助?
spark上下文如何读取用户代码并将其转换为任务?
答案 0 :(得分:9)
关于spark上下文如何读取用户代码并将其转换为任务?
驱动程序代码可生成作业,阶段和任务。
整个驱动程序代码可以作为一个应用程序调用,每个操作都构成一个作业。
当作业提交给司机时,作业分为逻辑计划和物理计划。
在逻辑计划期间,transformations()构建一系列RDD的计算。 由于每个action()触发一个作业,因此在物理计划期间,转换的完整依赖图被分为几个阶段。与hadoop不同,执行过程是固定的map-shuffle-sort-aggregate,spark没有固定的执行过程。当数据以流方式实际需要时计算数据。它从RDD的最终结果开始,并向后检查RDD链,以找出计算最终结果所需的RDD和parititons。在回溯期间,如果它遇到ShuffleDependency,它会切断数据流并形成一个新的阶段,通过NarrowDepedency离开RDD的链接。因此,ShuffleDependency突破了一个新阶段。
在每个阶段中,任务都被完成,数据通过转换进行流水线操作。任务数等于每个阶段的RDD中的分区数。
所有任务都打包在TaskSet中并发送到TaskScheduler。驱动程序actor将序列化的任务发送到工作节点上的CoarseGrainedExecutorBackend Actor。收到后,执行程序将其反序列化为正常任务并运行以获得结果。将通知TaskScheduler任务已完成,其结果将被处理
如果接收到的驱动程序任务是该阶段的最后一项任务,则将提交下一阶段。如果舞台已经是最后一个舞台,则会通知dagScheduler作业已完成。
从spark 1.4版本开始,Spark UI中添加了新的可视化。我们可以在哪里看到不同阶段的DAG可视化。
答案 1 :(得分:5)
从根本上传递的Spark函数基于Java Serialization。在Java中,您可以将任意代码传递给网络上的其他机器,可以是简单的案例类或任何具有任何行为的类。
只有一个要求 - 序列化类需要位于目标JVM的类路径中。
在启动时使用spark-submit
它将您的jar
文件分发给所有Spark工作节点,它允许驱动程序将序列化函数传递给工作节点,并且因为序列化类在类路径中是任何函数从驱动程序发送可以反序列化。
Spark没有为RDD转换定义任何特定的Task
类。如果您使用Scala进行map
操作,则会发送scala Function1
的序列化版本。
如果您使用按键等的aggregate / reduce等,则可以是Function2
。无论如何,它不是Spark特有的,它只是简单的Scala(Java)类。
答案 2 :(得分:0)
一点解释:
执行程序如何知道包含在任务类中的需要执行的方法是什么?
执行程序接收带有任务描述的RPC消息,见下文
序列化到底有何帮助?
是的,该任务包含由closureSerializer
序列化的代码spark上下文如何读取用户代码并将其转换为任务?
在REPL环境中,spark将用户代码编译为类文件并放在文件服务器上,执行程序实现了一个自定义类加载器,它从驱动程序端的文件服务器加载类;该类实际上是一个针对记录迭代器运行的函数