Spark的调度流程—详细、易懂、面试

本文详细介绍了Spark的任务调度过程,包括从DriverProgram提交程序到SparkContext,再到DAGScheduler和TaskScheduler的具体步骤。深入探讨了如何将作业划分为不同的stage,并在集群中执行任务的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看一下Spark调度过程的流程图。这张图很不错:


具体流程如下:

1)DriverProgram即用户提交的程序定义并创建了SparkContext的实例,SparkContext会根据RDD对象构建DAG图,然后将作业(job)提交(runJob)给DAGScheduler。

2)DAGScheduler对作业的DAG图进行切分成不同的stage[stage是根据shuffle为单位进行划分],每个stage都是任务的集合(taskset)并以taskset为单位提交(submitTasks)给TaskScheduler。

3)TaskScheduler通过TaskSetManager管理任务(task)并通过集群中的资源管理器(Cluster Manager)[standalone模式下是Master,yarn模式下是ResourceManager]把任务(task)发给集群中的Worker的Executor, 期间如果某个任务(task)失败, TaskScheduler会重试,TaskScheduler发现某个任务(task)一直未运行完成,有可能在不同机器启动一个推测执行任务(与原任务一样),哪个任务(task)先运行完就用哪个任务(task)的结果。无论任务(task)运行成功或者失败,TaskScheduler都会向DAGScheduler汇报当前状态,如果某个stage运行失败,TaskScheduler会通知DAGScheduler可能会重新提交任务。

4)Worker接收到的是任务(task),执行任务(task)的是进程中的线程,一个进程中可以有多个线程工作进而可以处理多个数据分片,执行任务(task)、读取或存储数据。

### Spark中DAG调度流程详解 #### 任务提交与执行 当用户提交一个Spark作业时,例如通过`rdd.collect()`触发的行动操作,Spark会将此操作转化为一个或多个Job。每个Job会被进一步分解为Stage,而Stage是基于宽依赖(Shuffle Dependency)划分的[^2]。在Stage内部的任务称为Task,这些Task会在Executor上并行执行。 #### DAG生成过程 DAG(有向无环图)是在Spark调度器中生成的,它表示了RDD之间的转换关系。对于以下代码片段: ```scala val rdd = sc.textFile("hdfs://data.txt") .flatMap(_.split(" ")) .map((_, 1)) .reduceByKey(_ + _) rdd.collect() ``` 上述代码中的`flatMap`和`map`操作属于窄依赖,而`reduceByKey`引入了Shuffle操作,因此会形成一个新的Stage。整个DAG由多个Stage组成,Stage之间通过Shuffle进行数据交换[^2]。 #### 调度器组件 Spark调度器主要由以下几个部分组成: - **DAGScheduler**:负责将Job分解为多个Stage,并生成TaskSet。它还负责处理Stage之间的依赖关系。 - **TaskScheduler**:负责将Task分配给Worker节点上的Executor执行,并与集群管理器(如YARN或K8s)通信以获取资源。 - **SchedulerBackend**:与集群管理器交互,管理Executor资源的申请、释放等操作[^2]。 #### 资源管理与任务分配 在任务分配过程中,SchedulerBackend会根据集群管理器的反馈动态调整资源分配策略。例如,在YARN模式下,SchedulerBackend会通过YARN ResourceManager申请Container资源,并将Task分配到对应的Container中执行[^2]。 #### 性能监控与优化 Spark Web UI是一个重要的工具,用于可视化DAG的构建和执行情况。通过Web UI,用户可以查看每个Stage的执行时间、Shuffle读写量以及Task的分布情况,从而更好地理解和优化Spark作业的性能[^1]。 #### 示例代码 以下是一个简单的Spark作业示例,展示了如何通过`collect`触发DAG的生成与执行: ```python from pyspark.sql import SparkSession spark = SparkSession.builder.appName("DAGExample").getOrCreate() data = spark.sparkContext.parallelize(["apple banana", "orange apple", "banana orange"]) word_counts = data.flatMap(lambda line: line.split(" ")) \ .map(lambda word: (word, 1)) \ .reduceByKey(lambda a, b: a + b) result = word_counts.collect() print(result) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值