假设以下情况:每次只有一个Spark作业在运行。
我目前了解到的
这是我对Spark中发生的事情的理解:
- 创建
SparkContext
时,每个工作节点启动一个执行器。执行器是单独的进程(JVM),连接回驱动程序。每个执行器都有驱动程序的jar包。退出驱动程序会关闭执行器。每个执行器可以持有一些分区。 - 当执行作业时,根据血统图创建执行计划。
- 执行作业被拆分成阶段,其中每个阶段包含尽可能多的相邻(在血统图中)转换和操作,但没有洗牌。因此阶段由洗牌分隔。
我了解到
- 任务是通过序列化函数对象从驱动程序发送到执行器的命令。
- 执行器使用驱动程序的jar包对命令(任务)进行反序列化并在某个分区上执行它。
但是
问题
如何将阶段拆分为任务?
具体来说:
- 任务是由转换和操作确定的,还是可以在一个任务中有多个转换/操作?
- 任务是由分区确定的(例如,每个阶段每个分区一个任务)。
- 任务是由节点确定的(例如,每个阶段每个节点一个任务)。
我认为的(仅部分答案,即使正确也一样)
在https://0x0fff.com/spark-architecture-shuffle中,使用图像解释了洗牌。
我的印象是每个阶段分成 #number-of-partitions 个任务,不考虑节点数量。
每个阶段分成 #number-of-partitions 个任务,不考虑节点数量。
对于第一张图片,我会有3个映射任务和3个归约任务。
对于来自0x0fff的图片,假设只有三个橙色和三个深绿色文件,则有8个映射任务和3个归约任务。
未解决问题
那是正确的吗?即使正确,我的问题还没有全部得到解答,因为仍然无法确定多个操作(例如多个映射)是否在一个任务中还是分成一个任务。
他人的说法
Spark中的任务是什么?Spark worker如何执行jar文件? 和 Apache Spark调度程序如何将文件拆分为任务? 与此类似,但我觉得其中并没有清晰地回答我的问题。