Chapter 01

Spark 核心架构

从 MapReduce 的痛点出发,理解 Spark 的 DAG 执行模型、分布式组件与 API 演进体系

MapReduce 的问题

在 Spark 出现之前,Hadoop MapReduce 是大数据处理的事实标准。MapReduce 的核心思想是将计算拆分为 Map(映射)和 Reduce(归约)两个阶段,中间结果必须写入 HDFS 磁盘。

MapReduce 的三大痛点

MapReduce vs Spark 的中间数据处理对比 MapReduce(每步都写磁盘): Input → Map → [HDFS写] → Shuffle → Reduce → [HDFS写] → Map → [HDFS写] → ... Spark(内存缓存,按需持久化): Input → Transform → [内存RDD] → Transform → [内存RDD] → Action → Output 迭代1 迭代2 迭代3 (只有最终结果写磁盘)

Spark 的诞生与核心思想

Apache Spark 由 Matei Zaharia 在 UC Berkeley AMPLab 于 2009 年创建,2013 年捐献给 Apache 基金会。Spark 的核心创新是 弹性分布式数据集(RDD):将数据集以分区形式分布在集群内存中,避免重复的磁盘读写,使迭代算法性能提升 10~100 倍。

Spark 的核心理念:把计算带到数据所在节点(移动计算而非移动数据),在内存中缓存中间结果,用 DAG 调度引擎优化整个计算流程。

核心架构:Driver / Executor / Cluster Manager

Spark 集群架构总览 ┌─────────────────────────────────────────────────────────────┐ │ Driver Program │ │ SparkContext / SparkSession │ │ ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │ │ │ DAG Scheduler│ │Task Scheduler│ │ Block Manager │ │ │ └──────┬───────┘ └──────┬───────┘ └─────────────────┘ │ └──────────┼─────────────────┼──────────────────────────────┘ │ 申请资源 │ 分发 Task ▼ ▼ ┌──────────────────┐ ┌─────────────────────────────────────┐ │ Cluster Manager │ │ Worker Node │ │ (YARN/K8s/ │ │ ┌──────────┐ ┌──────────────┐ │ │ Standalone) │ │ │ Executor │ │ Executor │ │ │ │ │ │ Task Task│ │ Task Task │ │ │ │ │ │ [内存缓存]│ │ [内存缓存] │ │ └──────────────────┘ │ └──────────┘ └──────────────┘ │ └─────────────────────────────────────┘

执行模型:DAG / Stage / Task / Shuffle

Spark 将用户的转换操作构建成一个 有向无环图(DAG),再由调度器将其分解为 Stage 和 Task 提交给 Executor 执行。

名词解释

RDD vs DataFrame vs Dataset 演进

Spark 经过多年发展,形成了三代 API,从底层到高层逐步封装:

API引入版本类型安全性能优化推荐场景
RDDSpark 1.0编译期安全(Scala)无 Catalyst/Tungsten 优化底层控制、自定义序列化
DataFrameSpark 1.3运行期检查Catalyst 优化器 + Tungsten 内存管理数据工程、SQL 分析(推荐)
DatasetSpark 1.6编译期安全(Scala/Java)同 DataFrame(本质是类型化 DataFrame)Scala/Java 强类型业务代码

Python 用户注意:PySpark 只有 DataFrame API(Python 没有编译期类型),Dataset API 仅在 Scala/Java 中有意义。绝大多数数据工程师使用 DataFrame API 就够了。

部署模式

模式适用场景特点
Local[n]本地开发/测试单机运行,n 为线程数,local[*] 使用全部 CPU
Standalone小型私有集群Spark 自带的轻量级 Cluster Manager,无需 Hadoop
YARNHadoop 生态与 HDFS 深度集成,企业最常见的部署方式
Kubernetes云原生/容器化Spark 3.1+ 生产就绪,弹性伸缩,现代首选
Databricks托管云平台全托管 Spark,Delta Lake 原生支持,无需运维

安装 PySpark + JupyterLab

# 前置条件:Java 11 或 17(Spark 3.3+ 推荐)
java -version   # 确认已安装

# 安装 PySpark 和 JupyterLab
pip install pyspark==3.5.1 jupyterlab findspark

# 启动 JupyterLab
jupyter lab

# 或者用 Docker(最简单,无需本地 Java)
docker run -it --rm \
  -p 8888:8888 \
  -p 4040:4040 \
  jupyter/pyspark-notebook:spark-3.5.0
# 第一个 PySpark 程序
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .appName("HelloSpark") \
    .master("local[*]") \
    .getOrCreate()

# Spark UI 运行在 http://localhost:4040
print(f"Spark 版本: {spark.version}")

# 创建一个简单的 DataFrame
data = [("Alice", 30), ("Bob", 25), ("Charlie", 35)]
df = spark.createDataFrame(data, ["name", "age"])
df.show()

# +-------+---+
# |   name|age|
# +-------+---+
# |  Alice| 30|
# |    Bob| 25|
# |Charlie| 35|
# +-------+---+

spark.stop()

Spark UI(端口 4040):每个 Spark 应用运行时会启动 Web UI,可以实时查看 Job、Stage、Task 的执行状态、数据量、耗时分布。调优时这是最重要的工具,务必养成查看 Spark UI 的习惯。