# Spark 学习项目 基于 **Scala + Java** 的 Apache Spark 学习与练习项目。 本项目主要用于个人学习和记录 Spark,从 Spark 基础、RDD、PairRDD、Shuffle、Partition 逐步深入,同时保留线下课程中的 DataFrame、缓存、Checkpoint、YARN 提交等示例代码。 项目以 **Scala 为主,Java 为辅**,代码按照课程进行拆分,每一课尽量保持独立,方便学习、复习和实验。 --- ## 项目目标 通过循序渐进的练习掌握 Spark Core 的核心概念,并逐步过渡到 Spark SQL。 学习重点包括: - Spark 应用程序的基本结构 - `SparkConf`、`SparkContext` - RDD 的创建、转换和行动 - `map`、`filter`、`flatMap`、`reduce`、`foreach` - PairRDD 与 `reduceByKey` - `groupByKey` 与 `reduceByKey` - Shuffle 的基本原理 - RDD Partition 分区 - `glom`、`repartition`、`coalesce` - `partitionBy` - 自定义 `Partitioner` - WordCount - Spark SQL / DataFrame - Cache、Persist、Checkpoint - Spark 程序打包及 YARN 提交 --- ## 技术栈 | 技术 | 版本 / 说明 | | --- | --- | | JDK | 8 | | Scala | 2.11.12 | | Apache Spark | 2.4.3 | | Hadoop Client | 2.7.3 | | MySQL | 8.0.28 | | HikariCP | 4.0.3 | | commons-dbutils | 1.6 | | JUnit | 3.8.1 | | 构建工具 | Maven 3 | | Scala Maven Plugin | 4.8.1 | | Maven Assembly Plugin | 3.7.1 | 项目 `pom.xml` 当前固定使用 **Java 8 + Scala 2.11.12 + Spark 2.4.3**,因此建议使用对应版本的 JDK 和依赖环境。 --- ## 项目结构 ```text spark_20260915/ ├── pom.xml ├── README.md ├── AGENTS.md │ ├── src/ │ ├── main/ │ │ ├── java/ │ │ │ └── org/example/ │ │ │ └── core/ │ │ │ ├── GroupByKeyDemo.java │ │ │ ├── MyPartitioner.java │ │ │ ├── RddCreateDemo.java │ │ │ └── RepartitionVsCoalesce.java │ │ │ │ │ ├── scala/ │ │ │ └── org/ │ │ │ ├── example/ │ │ │ │ ├── App.scala │ │ │ │ ├── test.scala │ │ │ │ ├── core/ │ │ │ │ └── sql/ │ │ │ │ │ │ │ └── exercises/ │ │ │ ├── exercises1/ │ │ │ ├── exercises2/ │ │ │ ├── exercises3/ │ │ │ ├── exercises4/ │ │ │ └── exercises5/ │ │ │ │ │ └── resources/ │ │ ├── log4j.properties │ │ ├── word.txt │ │ └── create_table.sql │ │ │ └── test/ │ └── java/ │ └── target/ ``` ### 目录说明 #### `org/example` 主要存放课程外的 Demo、线下课程代码以及一些完整示例。 其中: ```text org/example/core/ ``` 主要用于演示 Spark Core 基础功能,包括: - RDD 创建 - `groupByKey` - 自定义 `Partitioner` - `repartition` - `coalesce` 同时存在 Java 与 Scala 两套实现,用于对比两种语言编写 Spark 程序的方式。 ```text org/example/sql/ ``` 用于存放 Spark SQL / DataFrame 相关示例,例如通过 `SparkSession` 创建 DataFrame。 --- #### `org/exercises` 这是本项目最核心的学习目录。 每一课按照课程编号划分: ```text exercises1 exercises2 exercises3 exercises4 exercises5 ``` 通常将: ```text demo/ ``` 用于课程演示代码, ```text exercises/ ``` 用于自己完成的课后练习。 这样可以把“看懂 Demo”和“自己写代码”区分开。 --- # 课程进度 ## 第 1 课:Spark 是什么,以及第一个 Spark 程序 目录: ```text src/main/scala/org/exercises/exercises1/ ``` 主要学习: - Spark 的基本概念 - `SparkConf` - `SparkContext` - 本地模式 `local` - 从集合创建 RDD - 从文件创建 RDD - Transformation - Action - 第一个 WordCount 这一课的目标是先建立 Spark 程序的整体结构。 --- ## 第 2 课:RDD 常用算子 目录: ```text src/main/scala/org/exercises/exercises2/ ``` 重点学习单值 RDD 的常见操作: | 练习 | 内容 | | --- | --- | | Ex 1 | `map` | | Ex 2 | `filter` | | Ex 3 | `flatMap` | | Ex 4 | `reduce` | | Ex 5 | `foreach` | 通过这些练习理解: ```text RDD ↓ Transformation ↓ Action ``` 并逐渐熟悉 Scala 函数、匿名函数以及 Spark 算子的使用方式。 --- ## 第 3 课:PairRDD 与 reduceByKey 目录: ```text src/main/scala/org/exercises/exercises3/ ``` 重点学习: - `(K, V)` 类型的 PairRDD - `map` - `reduceByKey` - WordCount 核心代码结构: ```scala rdd .flatMap(...) .map(...) .reduceByKey(...) .collect() ``` 这一课开始正式进入 Spark 中非常重要的 **Key-Value 数据处理模式**。 --- ## 第 4 课:groupByKey、reduceByKey 与 Shuffle 目录: ```text src/main/scala/org/exercises/exercises4/ ``` 重点学习: - `groupByKey` - `reduceByKey` - Shuffle - Map 端局部聚合 - 宽依赖与窄依赖 - 为什么 `reduceByKey` 通常比直接 `groupByKey` 更适合做聚合计算 通过实际 Demo 对比: ```text groupByKey ``` 和: ```text reduceByKey ``` 的数据处理过程,理解 Shuffle 在 Spark 中到底发生了什么。 --- ## 第 5 课:Partition 分区 目录: ```text src/main/scala/org/exercises/exercises5/ ``` 主要学习 Spark RDD 的分区机制。 重点内容: - `getNumPartitions` - `glom` - RDD 分区查看 - `repartition` - `coalesce` - `partitionBy` - 自定义 `Partitioner` - Key 到 Partition 的映射 例如自定义分区器: ```scala class MyPartitioner extends Partitioner { override def numPartitions: Int = 2 override def getPartition(key: Any): Int = { key.asInstanceOf[Int] % 2 } } ``` 通过代码理解: ```text RDD ↓ Partition ↓ Task ``` 以及 Key 如何决定数据最终进入哪个 Partition。 当前仓库 `main` 分支最新提交已经进入这一课。 --- # 线下课程 Demo 除了 ChatGPT 分课练习之外,仓库还保留了一些线下课程代码,用于补充 Spark 实际开发中的知识。 ## RDD 创建、操作与重分区 主要涉及: - RDD 创建 - RDD Transformation - RDD Action - `repartition` - `coalesce` - Partition --- ## Cache / Persist / Checkpoint 用于理解 Spark 中的数据持久化机制,包括: - `cache()` - `persist()` - `checkpoint()` - Checkpoint 目录 - RDD 血缘关系 - 长依赖链优化 同时包含 Spark 程序打包以及向 YARN 提交运行的相关学习内容。 --- ## Spark SQL / DataFrame 目录: ```text src/main/scala/org/example/sql/ ``` 当前已有 DataFrame 创建示例,通过: ```scala SparkSession ``` 创建 Spark 应用,然后: ```scala import spark.implicits._ val df = data.toDF() df.show() df.printSchema() ``` 用于学习: - `SparkSession` - DataFrame - `toDF` - `show` - `printSchema` 当前仓库已经包含对应的 DataFrame Demo。 --- # WordCount 项目中多处使用 WordCount 作为学习案例。 典型流程: ```text 文本 ↓ flatMap ↓ 拆分单词 ↓ map ↓ (word, 1) ↓ reduceByKey ↓ 统计单词数量 ``` Scala 示例: ```scala val result = textFile .flatMap(_.split(" ")) .map(word => (word, 1)) .reduceByKey(_ + _) ``` WordCount 看起来简单,但可以贯穿整个 Spark 学习过程: ```text RDD ↓ Transformation ↓ PairRDD ↓ reduceByKey ↓ Shuffle ↓ Partition ``` 因此本项目会反复使用 WordCount 来帮助理解 Spark 的底层处理过程。 --- # Maven 构建 ## 拉取依赖 ```bash mvn -DskipTests dependency:resolve ``` ## 编译 ```bash mvn compile ``` ## 测试 ```bash mvn test ``` 目前测试目录主要用于预留,随着课程推进逐步补充测试。 ## 打包 ```bash mvn package ``` 完成后会生成: ```text target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar ``` 项目目前使用 `scala-maven-plugin` 编译 Scala,并使用 `maven-assembly-plugin` 打包包含依赖的 Fat JAR。 --- # 运行程序 ## IntelliJ IDEA 推荐直接在 IntelliJ IDEA 中运行。 打开: ```text pom.xml ``` 等待 Maven 加载完成后,可以直接找到带有: ```scala def main(args: Array[String]): Unit ``` 的 Scala `object` 运行。 例如: ```text org.example.App ``` 或者: ```text org.exercises.exercises5.demo.Demo ``` 具体运行哪个类,根据当前学习章节选择即可。 --- ## 命令行运行 Fat JAR 例如: ```bash java -cp target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar org.example.App ``` 项目主要用于本地学习和实验,不要求先搭建真正的 Spark 集群。 --- # 学习方式 本项目建议按照下面的方式学习: ```text 先看 Demo ↓ 理解代码 ↓ 自己完成 Exercises ↓ 运行并观察结果 ↓ 修改代码验证结论 ↓ 记录到 Git ``` 尤其是学习 Spark 时,不建议只看最终输出。 例如学习 Partition 时,可以通过: ```scala rdd.getNumPartitions rdd.glom().collect() ``` 直接观察不同 Partition 中的数据。 学习 Shuffle 时,则重点观察: ```text 数据在不同 Partition 之间如何重新分布 ``` 这样比单纯记住 API 更容易真正理解 Spark。 --- # Git 提交规范 当前项目采用简洁的中文 Commit Message。 推荐格式: ```text feat:ChatGPT 第 X 课:课程主题 ``` 例如: ```text feat:ChatGPT 第 1 课:Spark 是什么,以及第一个 Spark 程序 feat:ChatGPT 第 2 课:RDD 常用算子 feat:ChatGPT 第 3 课:PairRDD 与 reduceByKey feat:ChatGPT 第 4 课:groupByKey、reduceByKey 与 Shuffle feat:ChatGPT 第 5 课:Partition 分区 ``` 其他类型: ```text docs:README build:更新 Maven 依赖 ``` 建议一节课一个主要 Commit,一道独立练习尽量保持原子提交。 --- # 开发约定 ### Java / Scala 项目同时保留 Java 和 Scala 两套实现。 学习阶段以 Scala 为主,Java Demo 主要用于: - 对照 Spark API - 理解 Java 与 Scala 的写法差异 - 复习 Spark 基础 API 新课程练习优先使用 Scala。 ### Spark 模式 学习阶段主要使用: ```scala .setMaster("local") ``` 或者: ```scala .setMaster("local[2]") ``` 部分 DataFrame Demo 使用本地多线程模式。 整个项目定位是: > **本地 Spark 学习、实验与知识整理仓库** 而不是生产环境 Spark 项目。 --- # MySQL / JDBC 扩展 项目 Maven 依赖中已经包含: - MySQL Connector - HikariCP - commons-dbutils 资源目录中也保留: ```text src/main/resources/create_table.sql ``` 用于后续 Spark 数据处理结果写入 MySQL 的实验。 后续可以继续完善: ```text Spark ↓ RDD / DataFrame ↓ 数据分析 ↓ JDBC ↓ MySQL ``` 逐步从 Spark 基础练习过渡到实际的数据处理流程。 --- # 当前学习进度 ```text ✅ 第 1 课:Spark 入门 ✅ 第 2 课:RDD 常用算子 ✅ 第 3 课:PairRDD 与 reduceByKey ✅ 第 4 课:groupByKey、reduceByKey 与 Shuffle ✅ 第 5 课:Partition 分区 ✅ 线下课:RDD 创建 / 操作 / 重分区 ✅ 线下课:Cache / Persist / Checkpoint ✅ 线下课:Spark 程序打包 / YARN ✅ 线下课:创建 DataFrame ⬜ 后续课程:继续学习 Spark Core ⬜ 后续课程:Spark SQL / DataFrame 深入 ⬜ 后续课程:真实数据分析案例 ``` --- # 后续规划 后续按照课程继续补充: ```text Spark Core ↓ RDD ↓ Shuffle ↓ Partition ↓ 持久化 ↓ 广播变量 / 累加器 ↓ Spark SQL ↓ DataFrame ↓ 数据分析案例 ↓ MySQL / JDBC ``` 项目会尽量保持: - 一课一目录 - Demo 与 Exercises 分离 - 代码可以直接运行 - 中文注释辅助理解 - 每个知识点配合实际输出验证 - 用 Git 记录学习进度 --- ## 项目定位 这是一个以 **“边学、边写、边运行、边总结”** 为核心的 Spark 学习仓库。 相比只保存课堂代码,本项目更关注: ```text 为什么这么写 ↓ 代码实际做了什么 ↓ Spark 底层发生了什么 ↓ 运行结果为什么是这样 ``` 通过持续增加 Demo 和练习,将 Spark 的知识点逐渐串联起来,形成一套完整的个人学习笔记与实践代码库。