# Spark 学习项目
> 仓库:[`KennethCheng/spark_20260915`](https://gitea.kennethcheng.cc/KennethCheng/spark_20260915)
这是我的 **Scala + Spark 学习与练习项目**,主要用于记录跟随课程学习 Spark 的过程,并把课堂 Demo、课后练习和实际运行实验整理到同一个 Maven 项目中。
当前学习重点以 **Spark Core / RDD** 为主,并逐步过渡到 **Spark SQL / DataFrame / Hive / JDBC**。
---
## 学习方式
项目中的代码主要分成两类:
- `chapter`:线下课程内容、课堂 Demo、知识点验证
- `practise`:配合 ChatGPT 学习完成的课后练习
代码统一放在 Maven 的 `src/main/scala` / `src/main/java` 下,尽量保持一个知识点一个 Demo,方便单独运行和复习。
提交信息统一使用中文,例如:
```text
feat:线下课:集合_...
feat:ChatGPT第 7 课:缓存 Cache / Persist + mapPartitions
```
---
## 技术栈
| 类别 | 版本 |
| --- | --- |
| JDK | Java 8 |
| Scala | 2.11.12 |
| Apache Spark | 2.4.3 |
| Hadoop Client | 2.7.3 |
| Maven | Maven 3 |
| scala-maven-plugin | 4.8.1 |
| maven-assembly-plugin | 3.7.1 |
| MySQL Connector | 8.0.28 |
| HikariCP | 4.0.3 |
| commons-dbutils | 1.6 |
> 项目以 **Spark 2.4.3 + Scala 2.11 + JDK 8** 为基准,运行环境不要随意升级 JVM / Scala 版本。
---
## 项目结构
```text
spark_project/
├── pom.xml
├── AGENTS.md
├── README.md
│
├── src/main/java/org/example/
│ ├── core/
│ │ ├── GroupByKeyDemo.java
│ │ ├── MyPartitioner.java
│ │ ├── RddCreateDemo.java
│ │ └── RepartitionVsCoalesce.java
│ └── AppTest.java
│
├── src/main/scala/org/example/
│ ├── App.scala
│ ├── test.scala
│ └── core/
│ ├── GroupByKeyDemo.scala
│ ├── MyPartitioner.scala
│ ├── RddCreateDemo.scala
│ └── RepartitionVsCoalesce.scala
│
├── src/main/scala/org/exercises/
│ ├── exercises1/
│ ├── exercises2/
│ ├── exercises3/
│ └── ...
│
└── src/main/resources/
├── create_table.sql
├── log4j.properties
└── word.txt
```
---
## Spark 学习进度
### 第 1 课:Spark 入门
主要内容:
- `SparkConf`
- `SparkContext`
- `parallelize`
- 从文件创建 RDD
- Spark 程序基本运行方式
- Transformation / Action 基本概念
对应练习:
```text
src/main/scala/org/exercises/exercises1/
```
---
### 第 2 课:RDD 常用算子
主要学习:
- `map`
- `filter`
- `flatMap`
- `reduce`
- `foreach`
重点理解:
```text
Transformation
↓
生成新的 RDD
↓
继续构建计算链
Action
↓
触发 Job 执行
↓
返回结果 / 输出结果
```
对应练习:
```text
src/main/scala/org/exercises/exercises2/
```
---
### 第 3 课:PairRDD / WordCount
主要学习:
- `(K, V)` 键值对 RDD
- `map` 生成 PairRDD
- `reduceByKey`
- WordCount
- `groupByKey`
- shuffle 的基本概念
典型流程:
```text
文本
↓
flatMap
↓
map
↓
reduceByKey
↓
collect
```
对应练习:
```text
src/main/scala/org/exercises/exercises3/
```
---
### 第 4~5 课:Scala 函数基础 + Spark 分区
Scala 部分重点:
- `def`
- `=>`
- `map`
- 函数作为参数
- `_` 下划线简写
- Lambda / 函数值
- 函数参数与返回值
Spark 部分重点:
- Partition
- `getNumPartitions`
- `glom`
- `mapPartitions`
- `partitionBy`
- 自定义 `Partitioner`
- `groupByKey`
- `reduceByKey`
- `repartition`
- `coalesce`
项目中的核心 Demo:
```text
src/main/scala/org/example/core/
src/main/java/org/example/core/
```
---
### 第 6~7 课:RDD 执行过程与缓存
主要内容:
- Transformation 与 Action
- Lazy Evaluation
- DAG
- Job / Stage / Task
- Cache
- Persist
- `mapPartitions`
- 多次 Action 时为什么缓存可能提升性能
- Spark UI 中查看 Job / Stage / Task
重点认识:
```text
Transformation
↓
只记录计算逻辑
↓
Action
↓
真正触发 Job
```
以及:
```text
RDD
├── cache()
└── persist(...)
```
缓存不是“加了就一定更快”,只有同一个 RDD 被重复使用、重新计算成本较高时,收益才比较明显。
---
### 第 8 课:flatMap 与嵌套集合
主要学习:
- `map` 与 `flatMap` 的区别
- 嵌套集合处理
- 一对多转换
- WordCount 中为什么常用 `flatMap`
- 不使用 `flatMap` 的替代实现
典型理解:
```text
map
1 -> List(1, 2)
2 -> List(3, 4)
结果:
List(List(1, 2), List(3, 4))
```
```text
flatMap
1 -> List(1, 2)
2 -> List(3, 4)
结果:
List(1, 2, 3, 4)
```
---
### 第 9 课:排序与分组
主要学习:
- `sortBy`
- `sortWith`
- `groupBy`
- 分组后 `Iterable / CompactBuffer` 的理解
- 排序与分组的使用场景
- PairRDD 与普通 RDD 的进一步操作
常见写法:
```scala
rdd.sortBy(_._2)
rdd.sortWith((a, b) => a._2 > b._2)
rdd.groupBy(_ % 2)
```
---
## 当前已掌握的 RDD 知识体系
```text
Spark
│
├── SparkConf / SparkContext
│
├── RDD
│ ├── 创建
│ │ ├── parallelize
│ │ └── textFile
│ │
│ ├── Transformation
│ │ ├── map
│ │ ├── filter
│ │ ├── flatMap
│ │ ├── mapPartitions
│ │ ├── groupBy
│ │ ├── sortBy
│ │ ├── sortWith
│ │ └── reduceByKey
│ │
│ ├── Action
│ │ ├── collect
│ │ ├── count
│ │ ├── reduce
│ │ └── foreach
│ │
│ ├── Partition
│ │ ├── glom
│ │ ├── getNumPartitions
│ │ ├── partitionBy
│ │ ├── repartition
│ │ └── coalesce
│ │
│ └── 性能
│ ├── cache
│ ├── persist
│ └── Lazy Evaluation
│
└── PairRDD
├── reduceByKey
├── groupByKey
└── 自定义 Partitioner
```
---
## Spark SQL / DataFrame / Hive
RDD 基础阶段完成后,项目继续进入 Spark SQL 相关内容:
- `SparkSession`
- DataFrame
- DataSet 基础概念
- Schema
- DSL 查询
- SQL 查询
- JDBC
- Hive 支持
- Spark Thrift Server
- DBeaver 连接 Spark SQL
- DataFrame 与 JDBC 数据写入
目前已经开始接触:
```scala
val spark = SparkSession.builder()
.appName("Spark On Hive")
.enableHiveSupport()
.getOrCreate()
```
以及:
```scala
spark.sql("show databases")
spark.sql("show tables")
spark.sql("select ...")
```
后续会把 RDD 学到的思想逐步对应到 DataFrame / SQL 中。
---
## Spark 集群实践
除了本地 `local` 模式,还会进行 Spark 集群环境实验。
已经实践过的内容包括:
- `spark-submit`
- Yarn Client
- HDFS
- Spark UI
- Spark History Server
- Hive / Hive Metastore
- Spark Thrift Server
- Beeline
- DBeaver
- Spark SQL
例如:
```bash
spark-submit \
--master yarn \
--deploy-mode client \
--class org.example.core.App2 \
spark_project-1.0-SNAPSHOT.jar
```
---
## 快速开始
### 1. 准备环境
确保本机具备:
```text
JDK 8
Scala 2.11.x
Maven 3.x
```
### 2. 编译
```bash
mvn -DskipTests dependency:resolve
mvn compile
```
### 3. 打包
```bash
mvn package
```
生成:
```text
target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar
```
### 4. IDEA 运行
在 IntelliJ IDEA 中直接运行 Scala / Java 中的 `object` 或 `main` 方法即可。
---
## 本地 Spark UI
本地运行 Spark 程序时,可以通过 Spark Web UI 查看:
```text
http://localhost:4040
```
常见页面:
```text
Jobs
Stages
Storage
Environment
Executors
SQL
```
注意:
- `4040` 是当前 Spark Application 的 Web UI 端口
- Application 结束后,4040 通常就不再提供该 Application 的实时页面
- `18080` 是 Spark History Server,不是本地运行 Application 的实时 UI
---
## MySQL / JDBC
`src/main/resources/create_table.sql` 中保留了后续分析结果的目标表。
目前主要规划:
```text
Spark DataFrame
↓
聚合分析
↓
JDBC 写入
↓
MySQL
```
目标表:
| 表名 | 用途 |
| --- | --- |
| `top_ten_avg_ratings` | Top10 平均评分电影 |
| `genres_average_rating` | 类型平均评分 |
相关依赖:
```text
mysql-connector-java
HikariCP
commons-dbutils
```
---
## 代码规范
### Demo 命名
按课程 / 知识点拆分 Demo,尽量保持:
```text
Demo1xxx
Demo2xxx
...
```
### Commit
推荐:
```text
feat:线下课:集合_...
feat:ChatGPT第 7 课:缓存 Cache / Persist + mapPartitions
fix:修复 ...
docs:更新 README
refactor:重构 ...
```
每个知识点尽量保持一个独立 commit,便于后续按课程回看。
---
## 学习目标
最终形成一套完整的 Spark 学习路线:
```text
Scala 基础
↓
RDD 基础
↓
PairRDD
↓
Partition / Shuffle
↓
Cache / DAG / Stage / Task
↓
Spark SQL / DataFrame
↓
Hive
↓
JDBC
↓
Spark Thrift Server
↓
Yarn / 集群运行
↓
完整数据分析项目
```
重点不是只记 API,而是逐步理解:
```text
代码怎么写
↓
RDD 怎么产生
↓
Transformation 怎么串起来
↓
Action 什么时候触发
↓
Spark 如何拆成 Job / Stage / Task
↓
数据如何在 Partition 之间流动
↓
Shuffle 为什么发生
↓
为什么某些写法性能更好
```
---
## 学习记录
| 阶段 | 内容 | 状态 |
| --- | --- | --- |
| 01 | Spark 入门 | ✅ |
| 02 | RDD 常用算子 | ✅ |
| 03 | PairRDD / WordCount | ✅ |
| 04 | Scala 函数基础 | ✅ |
| 05 | 函数作为参数 / Partition | ✅ |
| 06 | RDD 执行与惰性计算 | ✅ |
| 07 | Cache / Persist / mapPartitions | ✅ |
| 08 | flatMap / 嵌套集合 | ✅ |
| 09 | sortBy / sortWith / groupBy | ✅ |
| 10+ | Spark SQL / DataFrame / Hive | 🚧 |
---
## 相关资源
- Apache Spark:
- Apache Hadoop:
- Apache Maven: