spark驱动程序如何序列化发送给执行程序的任务?
RDD通过对象中用户定义的函数/方法进行一系列转换。这些功能以任务的形式传递给执行者。 这些任务是在spark-core中定义的Scala类的实例。spark驱动程序如何序列化发送给执行程序的任务?
我假设用户定义的函数/方法被包装在一个任务对象中并传递给执行者。
如何执行人知道的是,需要执行 它被包裹在任务类中的方法?
序列化到底有多有用?
火花上下文如何读取用户代码并将其转换为任务?
一点解释:
如何执行者知道什么是需要被包裹在任务类要执行的方法是什么?
执行人收到任务描述一个RPC味精,见下文
究竟是怎样的序列化有帮助吗?
是,该任务包含由一个closureSerializer
连载怎样火花背景读取用户代码,并将其转换为任务的代码?
在REPL envirenment,火花编译用户代码的类文件,并把文件服务器上,执行器实现了一个自定义的类加载器,其装载从驾驶员侧的文件服务器的类;该类实际上是一个针对记录迭代器运行的函数
从根本上通过的Spark函数基于Java Serialization。在Java中,您可以通过网络将任意代码传递给其他机器,可以是简单的案例类或具有任何行为的任何类。
只有一个需求 - 序列化类需要位于目标JVM的类路径中。
在启动时,当您使用它的jar
文件分发到所有Spark工作节点,它可以让驾驶者序列化功能传递给工作节点,因为序列化类是在类路径可以反序列化,从驱动程序发送的任何功能。
Spark没有为RDD转换定义任何特定的Task
类。如果您使用Scala的map
操作,则会发送scala Function1
的序列化版本。
如果您通过密钥等使用聚合/减少,它可以是Function2
。无论如何,这不是Spark特有的,它只是普通的Scala(Java)类。
关于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可视化。