作为一个刚熬过Spark课程期末的过来人,我深知这门课的知识点有多散、多碎。从RDD的机制到Spark SQL的优化,从集群部署的资源分配到各种内存调优参数,每一个板块单独拎出来都够喝一壶的。我整理的这套复习笔记不是简单的概念罗列,而是围绕“Spark到底是怎么把一坨数据拆开、算完、再拼回来”这条主线,把核心原理、实操步骤和考试里那些高频的套路题都串了一遍。无论你是正在准备期末考还是面大数据的岗位,这份总结应该能帮你省下不少瞎翻书的时间。
1. Spark整体运行逻辑与核心架构
1.1 Spark到底是什么,以及它和Hadoop的区别
很多同学期末复习到一半,就开始混淆Spark和Hadoop的职责边界。考试也特别喜欢问这类对比题。一句话讲透:Hadoop里的MapReduce负责计算,但它每一步都要落盘,导致迭代计算和交互式查询慢得让人抓狂。Spark的核心创新就是“基于内存的计算”,把中间结果尽可能留在内存里,通过DAG(有向无环图)调度引擎来减少不必要的磁盘读写和任务启动开销。
从设计哲学上看,Spark的关键在于它给上层应用提供了统一的计算引擎,底层却可以跑在多种资源管理器上。它不只是替代MapReduce的批处理工具,而是一个能同时处理批处理、流计算、交互式查询和图计算的一体化平台。因此在实际项目中,Spark往往和HDFS搭配使用,Spark负责算,HDFS负责存,而Yarn则充当资源调度中枢。
1.2 核心组件与角色分工
Spark程序启动以后,背后会拉起一套完整的进程体系。理解这套体系是分析问题的基础。
- Driver:你的main方法跑在哪里,哪里就是Driver。它负责把用户代码转换成逻辑执行计划,再进一步切割成具体的任务集合,并且负责任务的调度、分发和状态汇总。很多人忽略的一点是,Driver不仅仅是控制中心,它还持有SparkContext这个核心对象,所有RDD的创建、转换和行动操作,都通过SparkContext向集群发起。
- Executor:真正干活的Worker,跑在Worker节点上的JVM进程。它有两个核心职责:执行Driver派发的Task,以及把RDD的缓存数据保存在自己的内存或本地磁盘里。Executor启动时会向Driver反向注册,并周期性上报心跳和执行状态。
- Worker / Slave节点:是集群中物理或虚拟机的角色,负责管理和监控所在节点的资源,并启动Executor进程。
- Task:被送到Executor上执行的最小工作单元。一个Executor默认可以同时跑多个Task,具体并发度取决于给它分配的CPU核心数。
整个流程可以串成一条线:Client提交任务 -> Driver解析代码并构建DAG -> DAG Scheduler根据依赖关系将图拆成多个Stage -> TaskScheduler把Stage中的每个Task分发给具体Executor -> Executor执行任务并回报结果或异常。
1.3 作业、Stage与Task三级调度体系
考试特别喜欢在这里挖坑,比如问“一个Action操作产生了1个Job,为什么这个Job里会包含好几个Stage,而且Stage之间还会出现Shuffle?”
其实原因在于Spark的懒执行模型。遇到transformation算子只要登记血缘关系就行,但遇到action算子(比如count、collect、saveAsTextFile)就必须真正计算了。此时DAG Scheduler会从触发计算的这个RDD出发,沿着血缘依赖一直往前回溯,遇到宽依赖(即父RDD的一个分区可能被子RDD的多个分区使用)就切一刀,新出一个Stage;遇到窄依赖则直接待在当前Stage里合并处理。
Stage划分规则是个考察重点:每个Stage内部的计算都是流水线式执行,尽可能让数据待在内存里按分区逐步算。而Stage之间是“前一个Stage算完才轮到下一个Stage”,中间的交接点就是Shuffle过程。所以一个Job的物理执行形态,就是按Stage执行序展开。TaskScheduler再将这些Stage中的任务集合下发到各Executor上。
1.4 考试里常见的架构细节提问
- Spark的Master和Worker是干什么的? 独立模式下的Master负责资源调度和集群管理,维护整个集群的状态;Worker节点负责执行真正的工作。生产环境多数不需要自己搭Standalone,因为资源回收和分配能力不如生产级资源管理器强。
- 为什么Driver挂了整个任务就断了? Driver是整个应用的大脑,它的状态就是应用状态。一旦Driver进程退出,SparkContext也就失效,所有Executor会被强制回收,作业直接失败,也因此才有了后来各种恢复机制的设计。
- 一个Executor的并发能力怎么决定? 取决于分配给它的CPU核数。假设每个Executor分配2个vcore,那么它最多同时跑2个任务。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. RDD编程模型与运行机制深度拆解
2.1 RDD五大属性及其重要性
RDD(弹性分布式数据集)是Spark中最基础的数据抽象。它的五个关键属性不仅是面试必问,也是理解后面所有优化手段的前提。
- 分区列表:一个RDD由多个分区构成,每个分区对应数据集合的一个子集。分区数量决定了并行度,同时也直接决定产生多少个Task。
- 分区器:对于key-value型的RDD,会根据分区器决定数据按什么规则分发到哪个分区,常见的有HashPartitioner和RangePartitioner。只有key-value类型的RDD才可能被分区,普通RDD的分区器是None。
- 依赖关系:每个RDD都记录了它是从哪些父RDD转换而来的,这些依赖关系构成了DAG的边,也决定了容错和计算方式。
- 首选位置:优先将计算调度到数据所在的节点进行本地读取,从而减少网络传输开销。
- 计算函数:Spark并不真正在每个分区里预先存储具体数据,它保存的是“如何计算得到一个分区数据”的函数,计算动作是惰性的,遇到行动操作才从头算。
考试理解的重点在于,RDD本身不存数据,它是一张“生产数据的图纸”。这也是为什么血缘关系极其重要,因为一旦某个分区数据在计算过程中丢失或损坏,Spark会按血缘关系,从原始数据源重新计算这个分区,而不需要重新计算整个数据集。
2.2 Transformation算子与Action算子的底层差异
对算子进行分类掌握是性价比很高的复习策略。
Transformation算子是懒执行,返回值还是RDD,不触发实际计算。常见的就是map、flatMap、filter、groupByKey、reduceByKey、sortByKey、distinct、union、join、cogroup等。考试需要重点理解的几个例子:
- filter在逻辑上是窄依赖,
