7 Spark 底层执行原理

devtools/2025/2/3 15:38:12/

7 Spark 底层执行原理

  • 1. 从代码角度看 DAG 图的构建
  • 2. 将 DAG 划分为 Stage 核心算法
  • 3. 将 DAG 划分为 Stage 剖析
  • 4. 提交 Stages
  • 5. 监控 Job、Task、Executor
  • 6. 获取任务执行结果
  • 7. 任务调度总体诠释
  • Spark 运行架构特点

Spark 运行流程
在这里插入图片描述

Spark运行流程
具体运行流程如下:
1.SparkContext 向资源管理器注册并向资源管理器申请运行 Executor
2.资源管理器分配 Executor,然后资源管理器启动 Executor
3.Executor 发送心跳至资源管理器
4.SparkContext 构建 DAG 有向无环图
5.将 DAG 分解成 Stage(TaskSet)
6.把 Stage 发送给 TaskScheduler
7.Executor 向 SparkContext 申请 Task
8.TaskScheduler 将 Task 发送给 Executor 运行
9.同时 SparkContext 将应用程序代码发放给 Executor
10.Task 在 Executor 上运行,运行完毕释放所有资源

1. 从代码角度看 DAG 图的构建

Val lines1 = sc.textFile(inputPath1).map(...).map(...)Val lines2 = sc.textFile(inputPath2).map(...)Val lines3 = sc.textFile(inputPath3)Val dtinone1 = lines2.union(lines3)Val dtinone = lines1.join(dtinone1)dtinone.saveAsTextFile(...)dtinone.filter(...).foreach(...)

上述代码的 DAG 图如下所示:
在这里插入图片描述

构建DAG图
Spark 内核会在需要计算发生的时刻绘制一张关于计算路径的有向无环图,也就是如上图所示的 DAG。
Spark 的计算发生在 RDD 的 Action 操作,而对 Action 之前的所有 Transformation,Spark 只是记录下 RDD 生成的轨迹,而不会触发真正的计算。

2. 将 DAG 划分为 Stage 核心算法

一个 Application 可以有多个 job 多个 Stage:
Spark Application 中可以因为不同的 Action 触发众多的 job,一个 Application 中可以有很多的 job,每个 job 是由一个或者多个 Stage 构成的,后面的 Stage 依赖于前面的 Stage,也就是说只有前面依赖的 Stage 计算完毕后,后面的 Stage 才会运行。
划分依据:
Stage 划分的依据就是宽依赖,像 reduceByKey,groupByKey 等算子,会导致宽依赖的产生。
回顾下宽窄依赖的划分原则:
窄依赖:父 RDD 的一个分区只会被子 RDD 的一个分区依赖。即一对一或者多对一的关系,可理解为独生子女。 常见的窄依赖有:map、filter、union、mapPartitions、mapValues、join(父 RDD 是 hash-partitioned)等。
宽依赖:父 RDD 的一个分区会被子 RDD 的多个分区依赖(涉及到 shuffle)。即一对多的关系,可理解为超生。 常见的宽依赖有 groupByKey、partitionBy、reduceByKey、join(父 RDD 不是 hash-partitioned)等。
核心算法:回溯算法
从后往前回溯/反向解析,遇到窄依赖加入本 Stage,遇见宽依赖进行 Stage 切分。
Spark 内核会从触发 Action 操作的那个 RDD 开始从后往前推,首先会为最后一个 RDD 创建一个 Stage,然后继续倒推,如果发现对某个 RDD 是宽依赖,那么就会将宽依赖的那个 RDD 创建一个新的 Stage,那个 RDD 就是新的 Stage 的最后一个 RDD。 然后依次类推,继续倒推,根据窄依赖或者宽依赖进行 Stage 的划分,直到所有的 RDD 全部遍历完成为止。

3. 将 DAG 划分为 Stage 剖析

在这里插入图片描述

DAG划分Stage
一个 Spark 程序可以有多个 DAG(有几个 Action,就有几个 DAG,上图最后只有一个 Action(图中未表现),那么就是一个 DAG)。
一个 DAG 可以有多个 Stage(根据宽依赖/shuffle 进行划分)。
同一个 Stage 可以有多个 Task 并行执行(task 数=分区数,如上图,Stage1 中有三个分区 P1、P2、P3,对应的也有三个 Task)。
可以看到这个 DAG 中只 reduceByKey 操作是一个宽依赖,Spark 内核会以此为边界将其前后划分成不同的 Stage。
同时我们可以注意到,在图中 Stage1 中,从 textFile 到 flatMap 到 map 都是窄依赖,这几步操作可以形成一个流水线操作,通过 flatMap 操作生成的 partition 可以不用等待整个 RDD 计算结束,而是继续进行 map 操作,这样大大提高了计算的效率。

4. 提交 Stages

调度阶段的提交,最终会被转换成一个任务集的提交,DAGScheduler 通过 TaskScheduler 接口提交任务集,这个任务集最终会触发 TaskScheduler 构建一个 TaskSetManager 的实例来管理这个任务集的生命周期,对于 DAGScheduler 来说,提交调度阶段的工作到此就完成了。
而 TaskScheduler 的具体实现则会在得到计算资源的时候,进一步通过 TaskSetManager 调度具体的任务到对应的 Executor 节点上进行运算。
在这里插入图片描述

5. 监控 Job、Task、Executor

1.DAGScheduler 监控 Job 与 Task:
要保证相互依赖的作业调度阶段能够得到顺利的调度执行,DAGScheduler 需要监控当前作业调度阶段乃至任务的完成情况。
这通过对外暴露一系列的回调函数来实现的,对于 TaskScheduler 来说,这些回调函数主要包括任务的开始结束失败、任务集的失败,DAGScheduler 根据这些任务的生命周期信息进一步维护作业和调度阶段的状态信息。
2.DAGScheduler 监控 Executor 的生命状态:
TaskScheduler 通过回调函数通知 DAGScheduler 具体的 Executor 的生命状态,如果某一个 Executor 崩溃了,则对应的调度阶段任务集的 ShuffleMapTask 的输出结果也将标志为不可用,这将导致对应任务集状态的变更,进而重新执行相关计算任务,以获取丢失的相关数据。

6. 获取任务执行结果

1.结果 DAGScheduler:
一个具体的任务在 Executor 中执行完毕后,其结果需要以某种形式返回给 DAGScheduler,根据任务类型的不同,任务结果的返回方式也不同。
2.两种结果,中间结果与最终结果:
对于 FinalStage 所对应的任务,返回给 DAGScheduler 的是运算结果本身。
而对于中间调度阶段对应的任务 ShuffleMapTask,返回给 DAGScheduler 的是一个 MapStatus 里的相关存储信息,而非结果本身,这些存储位置信息将作为下一个调度阶段的任务获取输入数据的依据。
3.两种类型,DirectTaskResult 与 IndirectTaskResult:
根据任务结果大小的不同,ResultTask 返回的结果又分为两类:
如果结果足够小,则直接放在 DirectTaskResult 对象内中。
如果超过特定尺寸则在 Executor 端会将 DirectTaskResult 先序列化,再把序列化的结果作为一个数据块存放在 BlockManager 中,然后将 BlockManager 返回的 BlockID 放在 IndirectTaskResult 对象中返回给 TaskScheduler,TaskScheduler 进而调用 TaskResultGetter 将 IndirectTaskResult 中的 BlockID 取出并通过 BlockManager 最终取得对应的 DirectTaskResult。

7. 任务调度总体诠释

一张图说明任务总体调度:
在这里插入图片描述
任务总体调度

Spark 运行架构特点

  1. Executor 进程专属
    每个 Application 获取专属的 Executor 进程,该进程在 Application 期间一直驻留,并以多线程方式运行 Tasks。
    Spark Application 不能跨应用程序共享数据,除非将数据写入到外部存储系统。如图所示:
    在这里插入图片描述

Executor进程专属
2. 支持多种资源管理器
Spark 与资源管理器无关,只要能够获取 Executor 进程,并能保持相互通信就可以了。
Spark 支持资源管理器包含: Standalone、On Mesos、On YARN、Or On EC2。如图所示:
在这里插入图片描述

支持多种资源管理器
3. Job 提交就近原则
提交 SparkContext 的 Client 应该靠近 Worker 节点(运行 Executor 的节点),最好是在同一个 Rack(机架)里,因为 Spark Application 运行过程中 SparkContext 和 Executor 之间有大量的信息交换;
如果想在远程集群中运行,最好使用 RPC 将 SparkContext 提交给集群,不要远离 Worker 运行 SparkContext。
如图所示:
在这里插入图片描述

Job提交就近原则
4. 移动程序而非移动数据的原则执行
移动程序而非移动数据的原则执行,Task 采用了数据本地性和推测执行的优化机制。
关键方法:taskIdToLocations、getPreferedLocations。
如图所示:
在这里插入图片描述

数据本地性


http://www.ppmy.cn/devtools/155756.html

相关文章

ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务

目录 一、ASP.NET Core 中使用依赖注入 (DI) 容器获取并执行自定义服务 1. app.Services 2. GetRequiredService() 3. Init() 二、应用场景 三、依赖注入使用拓展 1、使用场景 2、使用步骤 1. 定义服务接口和实现类 2. 注册服务到依赖注入容器 3. 使用依赖注入获取并…

14 2D矩形模块( rect.rs)

一、 rect.rs源码 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or // http://www.apache.org/licenses/LICENS…

TypeScript语言的语法糖

TypeScript语言的语法糖 TypeScript作为一种由微软开发的开源编程语言&#xff0c;它在JavaScript的基础上添加了一些强类型的特性&#xff0c;使得开发者能够更好地进行大型应用程序的构建和维护。在TypeScript中&#xff0c;不仅包含了静态类型、接口、枚举等强大的特性&…

计算机毕业设计Python动漫推荐系统 漫画推荐系统 动漫视频推荐系统 机器学习 bilibili动漫爬虫 数据可视化 数据分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

vim的多文件操作

[rootxxx ~]# vim aa.txt bb.txt cc.txt #多文件操作 next #下一个文件 prev #上一个文件 first #第一个文件 last #最后一个文件 快捷键: ctrlshift^ #当前和上个之间切换 说明&#xff1a;快捷键ctrlshift^&#xff0c…

书生大模型实战营7

文章目录 L1——基础岛提示词工程实践什么是Prompt(提示词)什么是提示工程提示设计框架CRISPECO-STAR LangGPT结构化提示词LangGPT结构编写技巧构建全局思维链保持上下文语义一致性有机结合其他 Prompt 技巧 常用的提示词模块 浦语提示词工程实践(LangGPT版)自动化生成LangGPT提…

计算机网络网络层进阶:NAT、ARP 与 IP 系列技术全析!!!

一、网络地址转换NAT 私有IP 地址(内网IP)&#xff1a; 10.0.0.0~10.255.255.255 172.16.0.0~172.31.255.255 192.168.0.0~192.168.255.255 只允许分配给局域网内部的节点,不允许分配给互联网上的节点每个局域网内部都可以自行分配这些私有 IP 地址私有 IP 地址是可复用的&…

oracle: 多表查询之联合查询[交集intersect, 并集union,差集minus]

把多个查询结果上下合并, 即, 通过操作符将多个 SELECT 语句的结果集合并为一个结果集。虽然联合查询通常用于从多个表中检索数据&#xff0c;但它也可以用于从同一个表中检索不同的数据集。 联合查询: 交集,并集,差集 默认的排序规则通常是基于查询结果集中的列的自然顺序。…