Spark 的介绍与搭建:从理论到实践_spark环境搭建-****博客
Spark 的Standalone集群环境安装与测试-****博客
PySpark 本地开发环境搭建与实践-****博客
Spark 程序开发与提交:本地与集群模式全解析-****博客
Spark on YARN:Spark集群模式之Yarn模式的原理、搭建与实践-****博客
Spark 中 RDD 的诞生:原理、操作与分区规则-****博客
Spark 中的 RDD 分区的设定规则与高阶函数、Lambda 表达式详解-****博客
RDD 算子全面解析:从基础到进阶与面试要点-****博客
PySpark 数据处理实战:从基础操作到案例分析-****博客
Spark 的容错机制:保障数据处理的稳定性与高效性-****博客
Spark 共享变量:广播变量与累加器全解析-****博客
目录
一、Spark 核心概念解析
(一)架构层面概念
ClusterManager(统称)
Worker(统称)
(二)程序层面概念
Application
Driver
Executor
(三)运行层面概念
Job
Stage
Task
(四)Stage转换的TaskSet中Task个数由什么决定?
(五)降低分区可以不经过shuffle就实现,为什么有时候建议走Shuffle来降低分区?
(六) 在 spark 中什么模式下能访问 4040 界面?什么情况下能访问 8080 界面?
二、Spark 应用提交流程
(一)前提准备
(二)提交步骤
三、Spark 中的宽窄依赖
(一)依赖关系概述
(二)宽窄依赖定义与特点
窄依赖(Narrow Dependencies)
宽依赖(Wide/Shuffle Dependencies)
(三)标记宽窄依赖的意义
提高数据容错性能
提高数据转换性能
四、总结
Spark 作为大数据处理领域的重要框架,其复杂的架构和运行机制常常让初学者望而却步。本文将深入剖析 Spark 中的关键概念,包括 ClusterManager、Worker、Application、Driver、Executor、Job、Stage、Task 等,并详细讲解 Spark 应用的提交流程,以及宽窄依赖这一重要特性,旨在帮助读者全面理解 Spark 的工作原理,为进一步深入学习和应用 Spark 打下坚实基础。
一、Spark 核心概念解析
ClusterManager、Worker、Application、Driver、 Executor、Job、Stage、Task分别是什么
(一)架构层面概念
ClusterManager(统称)
分布式资源管理平台的主节点。在 Standalone 模式下是 Master,在 YARN 模式下是 ResourceManager。
主要功能包括管理从节点、接受客户端请求、进行资源管理和任务调度。它就像是整个分布式系统的指挥官,掌控着资源的分配和任务的派发大权。
Worker(统称)
分布式资源管理平台的从节点。对应 Standalone 模式下的 Worker 和 YARN 模式下的 NodeManager。
其职责是利用自身节点的资源去运行主节点分配的计算进程,是具体执行任务的 “士兵”,为整个分布式计算提供计算力支持。
(二)程序层面概念
Application
即 Spark 的应用程序,是开发者基于 Spark 的 API 开发的程序。在集群模式中,任何一个 Spark 程序都会包含一个 Driver 进程和多个 Executor 进程,而在单机模式下只有一个 Driver。可以在 4040 界面查看相关信息。
Driver
Spark 程序的驱动进程,类似于项目中的项目经理。它先启动,会调用 SparkContext 来实现自身功能,主要负责申请资源启动 Executor 进程,解析代码构建 Task、调度分配 Task、监控 Task 运行等一系列关键操作,是整个 Spark 应用程序的核心驱动力量。
Executor
Spark 程序的执行进程,是计算进程。后启动且运行在从节点中,使用从节点的 CPU 和内存(可通过参数如 --executor-mem 和 --executor-cores 进行配置)。其主要功能是负责运行 Driver 分配的 Task 分区,每个 Task 使用 1 Core CPU 来运行,并且可以将 Task 的数据缓存在内存中,是实际执行计算任务的单元。
(三)运行层面概念
Job
是 Spark 触发计算的最小单元。由 Driver 解析代码,遇到触发算子时就会构建 job。一个代码可以有多个触发算子,所以一个 Spark 程序可以包含多个 job。当 Job 被触发后,Driver 会调用 DAGScheduler 组件为其构建 DAG 图(执行计划)。
Stage
是 Spark 转换 Task 的最小单元。由 DAGScheduler 根据回溯算法构建整个 Job 的 DAG 图,在构建过程中会按照 Shuffle 过程(宽依赖)划分 Stage。每个 Stage 内部都是由 Task 直接在内存中转换完成,不同 Stage 之间需要经过磁盘来完成。根据数据处理过程,每一个Shuffle过程,就要构建一个 新的Stage,一个 job 中如果有 N 个 Shuffle,就会产生 N + 1 个 Stage。
Task
是 Spark 执行计算的最小单元。一个 Job 由多个 Stage 构成,每个 Stage 都会转换成为一个 TaskSet(Task 集合),每个 TaskSet 中可以包含多个 Task。Task 的个数由 Stage 中最后一个 RDD 的分区数或者最小的 RDD 分区数来决定(Spark 为避免资源浪费,选择用最少 Task 来完成)。最终 job 的所有 Task 都会由 Driver 按照优先本地计算的原则分配给不同的 Executor 去运行。
(四)Stage转换的TaskSet中Task个数由什么决定?
每个Stage会转换成一个TaskSet集合
TaskSet集合中Task的个数由这个Stage中最后一个RDD的分区数 或者 最小的RDD分区数来决定
Spark为了避免资源浪费,导致一部分Task工作,另一部分不工作,所以选择用最少Task来完成
(五)降低分区可以不经过shuffle就实现,为什么有时候建议走Shuffle来降低分区?
repartiton算子: 一般用于扩大分区数,底层调用的还是coalesce,是否经过shuffle写死了是True
coalesce算子:一般用于减少分区数,默认shuffle= False ,所以只用于减少分区,想扩大,手动shuffle= True
记住结论:
规则:调整分区个数,如果RDD的分区由N调整到M
N < M:增大分区:必须经过Shuffle才能实现
N > M:降低分区:可以经过Shuffle,也可以不经过
N远大于M:建议经过Shuffle来实现,N=1000, M=10
N和M差距不大:建议不经过Shuffle来实现,N=100, M=80
比例:超过10:1,建议走Shuffle
(六) 在 spark 中什么模式下能访问 4040 界面?什么情况下能访问 8080 界面?
单机版:可以看见4040
standalone 版:4040 和 8080 也都可以看见。
Yarn 版:只启动了 yarn,spark 任何程序都没有启动,所以 4040 和 8080 页面都访问不了,可以在 yarn 上查看,端口是 8088。
二、Spark 应用提交流程
spark任务提交执行流程图:(deploy-mode = client模式)
(一)前提准备
先启动分布式资源管理的集群,如 Spark Standalone 或 YARN。
(二)提交步骤
- 客户端提交用户开发好的 Spark Application 程序给 ClusterManager。
- ClusterManager 根据配置参数运行程序,启动 Driver 进程。
- Driver 进程向主节点提交申请启动 Executor 进程。
- 主节点根据资源配置和请求,在从节点上启动 Executor 进程。
- 所有 Executor 启动成功以后,会向 Driver 反向注册,等待分配 Task。
- Driver 解析代码,直到遇到触发算子,开始触发 job 的运行。
- Driver 会调用 DAGScheduler 组件为当前这个 job 通过回溯算法构建 DAG 图,并划分 Stage。
- Driver 会将这个 job 中每个 Stage 转换为 TaskSet,根据 Stage 中最后一个 RDD 分区数来构建 Task 个数。
- Driver 调用 TaskScheduler 将 Task 调度分配到 Executor 中运行。
三、Spark 中的宽窄依赖
(一)依赖关系概述
在 Spark 中,RDD 之间存在着依赖关系,这种依赖关系对于数据处理和任务调度有着重要的影响。
(二)宽窄依赖定义与特点
本质:只是一种标记,标记两个RDD之间的依赖关系
窄依赖(Narrow Dependencies)
定义:父 RDD 的一个分区的数据只给了子 RDD 的一个分区,无需经过 Shuffle。
特点:一对一或者多对一的关系,不经过 Shuffle,性能相对较快,但无法实现全局分区、排序、分组等操作。一个 Stage 内部的计算都是窄依赖的过程,全部在内存中完成。例如,map、filter 等算子产生的就是窄依赖。
宽依赖(Wide/Shuffle Dependencies)
定义:父 RDD 的一个分区的数据给了子 RDD 的多个分区,需要调用 Shuffle 的分区器来实现。
特点:一对多的关系,必须经过 Shuffle,性能相对较慢,但可以实现全局分区、排序、分组等操作。Spark 的 job 中按照宽依赖来划分 Stage。例如,reduceByKey 等涉及数据重分区的算子产生的就是宽依赖。
(三)标记宽窄依赖的意义
提高数据容错性能
当子 RDD 的某个分区的数据丢失时,如果没有标记宽窄依赖,不清楚父 RDD 与子 RDD 数据之间的关系,必须重新构建整个父 RDD 所有数据。而标记了宽窄依赖后,父 RDD 一个分区只对应子 RDD 的一个分区,按照对应关系恢复父 RDD 的对应分区即可,大大减少了数据恢复的工作量和资源消耗。
提高数据转换性能
对于多个算子的转换操作,如果不标记宽窄依赖,每个转换不知道会不会经过 Shuffle,都使用不同的 Task 来完成,每个 Task 的结果要保存到磁盘。而标记了宽窄依赖后,多个连续窄依赖算子放在一个 Stage 中,共用一套 Task 在内存中完成所有转换,避免了不必要的磁盘读写,提高了性能。
四、总结
通过对 Spark 中的 ClusterManager、Worker、Application、Driver、Executor、Job、Stage、Task 等核心概念的详细解析,以及对 Spark 应用提交流程和宽窄依赖特性的深入探讨,我们可以看到 Spark 构建了一个复杂而高效的分布式计算框架。理解这些概念和机制对于正确使用 Spark 进行大数据处理至关重要。无论是开发大规模数据处理应用,还是深入研究 Spark 的内部原理,都需要牢牢掌握这些知识要点。希望本文能够为读者在 Spark 的学习和应用之路上提供有益的参考和指引,让大家能够更加从容地驾驭 Spark 这一强大的大数据处理工具。