Spark 学习项目
这是我的 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,方便单独运行和复习。
提交信息统一使用中文,例如:
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 版本。
项目结构
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 入门
主要内容:
SparkConfSparkContextparallelize- 从文件创建 RDD
- Spark 程序基本运行方式
- Transformation / Action 基本概念
对应练习:
src/main/scala/org/exercises/exercises1/
第 2 课:RDD 常用算子
主要学习:
mapfilterflatMapreduceforeach
重点理解:
Transformation
↓
生成新的 RDD
↓
继续构建计算链
Action
↓
触发 Job 执行
↓
返回结果 / 输出结果
对应练习:
src/main/scala/org/exercises/exercises2/
第 3 课:PairRDD / WordCount
主要学习:
(K, V)键值对 RDDmap生成 PairRDDreduceByKey- WordCount
groupByKey- shuffle 的基本概念
典型流程:
文本
↓
flatMap
↓
map
↓
reduceByKey
↓
collect
对应练习:
src/main/scala/org/exercises/exercises3/
第 4~5 课:Scala 函数基础 + Spark 分区
Scala 部分重点:
def=>map- 函数作为参数
_下划线简写- Lambda / 函数值
- 函数参数与返回值
Spark 部分重点:
- Partition
getNumPartitionsglommapPartitionspartitionBy- 自定义
Partitioner groupByKeyreduceByKeyrepartitioncoalesce
项目中的核心 Demo:
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
重点认识:
Transformation
↓
只记录计算逻辑
↓
Action
↓
真正触发 Job
以及:
RDD
├── cache()
└── persist(...)
缓存不是“加了就一定更快”,只有同一个 RDD 被重复使用、重新计算成本较高时,收益才比较明显。
第 8 课:flatMap 与嵌套集合
主要学习:
map与flatMap的区别- 嵌套集合处理
- 一对多转换
- WordCount 中为什么常用
flatMap - 不使用
flatMap的替代实现
典型理解:
map
1 -> List(1, 2)
2 -> List(3, 4)
结果:
List(List(1, 2), List(3, 4))
flatMap
1 -> List(1, 2)
2 -> List(3, 4)
结果:
List(1, 2, 3, 4)
第 9 课:排序与分组
主要学习:
sortBysortWithgroupBy- 分组后
Iterable / CompactBuffer的理解 - 排序与分组的使用场景
- PairRDD 与普通 RDD 的进一步操作
常见写法:
rdd.sortBy(_._2)
rdd.sortWith((a, b) => a._2 > b._2)
rdd.groupBy(_ % 2)
当前已掌握的 RDD 知识体系
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 数据写入
目前已经开始接触:
val spark = SparkSession.builder()
.appName("Spark On Hive")
.enableHiveSupport()
.getOrCreate()
以及:
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
例如:
spark-submit \
--master yarn \
--deploy-mode client \
--class org.example.core.App2 \
spark_project-1.0-SNAPSHOT.jar
快速开始
1. 准备环境
确保本机具备:
JDK 8
Scala 2.11.x
Maven 3.x
2. 编译
mvn -DskipTests dependency:resolve
mvn compile
3. 打包
mvn package
生成:
target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar
4. IDEA 运行
在 IntelliJ IDEA 中直接运行 Scala / Java 中的 object 或 main 方法即可。
本地 Spark UI
本地运行 Spark 程序时,可以通过 Spark Web UI 查看:
http://localhost:4040
常见页面:
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 中保留了后续分析结果的目标表。
目前主要规划:
Spark DataFrame
↓
聚合分析
↓
JDBC 写入
↓
MySQL
目标表:
| 表名 | 用途 |
|---|---|
top_ten_avg_ratings |
Top10 平均评分电影 |
genres_average_rating |
类型平均评分 |
相关依赖:
mysql-connector-java
HikariCP
commons-dbutils
代码规范
Demo 命名
按课程 / 知识点拆分 Demo,尽量保持:
Demo1xxx
Demo2xxx
...
Commit
推荐:
feat:线下课:集合_...
feat:ChatGPT第 7 课:缓存 Cache / Persist + mapPartitions
fix:修复 ...
docs:更新 README
refactor:重构 ...
每个知识点尽量保持一个独立 commit,便于后续按课程回看。
学习目标
最终形成一套完整的 Spark 学习路线:
Scala 基础
↓
RDD 基础
↓
PairRDD
↓
Partition / Shuffle
↓
Cache / DAG / Stage / Task
↓
Spark SQL / DataFrame
↓
Hive
↓
JDBC
↓
Spark Thrift Server
↓
Yarn / 集群运行
↓
完整数据分析项目
重点不是只记 API,而是逐步理解:
代码怎么写
↓
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:https://spark.apache.org/
- Apache Hadoop:https://hadoop.apache.org/
- Apache Maven:https://maven.apache.org/