Apache Spark 中的任务划分(Task Scheduling)是一个关键的优化过程,它影响到整个Spark作业执行的效率和性能。以下是Spark中任务划分的基本概念:
-
Application (应用程序)
- 当启动一个Spark应用程序时,会初始化一个
SparkContext
,这标志着一个新的Spark应用实例的开始。
- 当启动一个Spark应用程序时,会初始化一个
-
Job (作业)
- 在Spark中,当用户调用一个Action操作(如
count()
、saveAsTextFile()
等)时,会触发一次Job提交。每个Job代表一个完整的数据处理流程,从读取数据源开始直到最终生成结果。
- 在Spark中,当用户调用一个Action操作(如
-
Stage (阶段)
- Job被划分为一系列的Stage,每个Stage是由一组并行的、相互之间没有shuffle依赖关系的任务组成的。Stage的划分主要基于RDD之间的依赖关系:窄依赖可以在一个Stage内完成;而遇到宽依赖(比如
groupByKey
、reduceByKey
等操作)时,则会在该点划分新的Stage。
- Job被划分为一系列的Stage,每个Stage是由一组并行的、相互之间没有shuffle依赖关系的任务组成的。Stage的划分主要基于RDD之间的依赖关系:窄依赖可以在一个Stage内完成;而遇到宽依赖(比如
-
TaskSet (任务集)
- 每个Stage对应一个TaskSet,即一组并行的任务集合。Task的数量取决于Stage最后一个RDD分区的数量,以及是否涉及到shuffle阶段。
-
Task (任务)
- Task是Spark中计算的最小单元,分为两种类型:
- ShuffleMapTask: 处理涉及shuffle的Stage,负责对数据进行partition,并将结果写入磁盘作为下一个Stage的数据来源。
- ResultTask: 负责执行最终Stage的计算,直接输出Job的最终结果。
- Task是Spark中计算的最小单元,分为两种类型:
-
并行度与资源分配
- Task的数量决定了作业的并行度,Spark Scheduler会根据集群中Executor的可用核心数等因素来决定如何最优地分配和调度这些任务。
在实际运行过程中,Spark的DAGScheduler首先将Job拆分成Stages,然后TaskScheduler将Stages进一步分解成Task,并将Task分配给各个Executor执行。这个过程确保了数据处理可以在分布式集群上高效并行运行。