Files
spark_20260915/README.md
T
2026-09-17 09:36:44 +08:00

180 lines
7.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Spark 学习项目(spark_project)
跟着 ChatGPT 课程的 Spark 学习笔记,用 **Scala + Java 双实现** 覆盖 Spark Core 的 RDD 基础、PairRDD、WordCount,并通过 MySQL 写入的示例表把练习串成一个迷你数仓案例。
> 课程三讲(一→三)一→一对应当前 `src/main/scala/org/exercises/exercises{1,2,3}` 三套练习;另有「线下课:RDD 创建/操作/重分区」的一份 Java 版 Demo。
## 技术栈
| 类别 | 版本 |
| ---------- | ------------------------------------------ |
| JVM | Java 8 |
| 语言 | Scala 2.11.12 + Java 8(双实现) |
| 计算引擎 | Apache Spark 2.4.3(core + sql) |
| 分布式 | Hadoop Client 2.7.3 |
| 数据库 | MySQL 8.0.28 |
| 连接池 | HikariCP 4.0.3 |
| JDBC 工具 | commons-dbutils 1.6 |
| 测试 | JUnit 3.8.1 |
| 构建 | Maven 3 + scala-maven-plugin 4.8.1 + maven-assembly-plugin 3.7.1 |
## 项目结构
```
spark_project/
├── pom.xml # Maven 配置(强制 JDK 8 / Scala 2.11)
├── src/main/java/org/example/
│ ├── core/
│ │ ├── GroupByKeyDemo.java # Java 版 4 个核心 Demo
│ │ ├── MyPartitioner.java
│ │ ├── RddCreateDemo.java
│ │ └── RepartitionVsCoalesce.java
│ └── AppTest.java # JUnit 默认骨架
├── src/main/scala/org/example/
│ ├── App.scala # Scala 入口:local[2] 模式 + word.txt WordCount
│ ├── test.scala
│ └── core/ # Scala 版同名 4 个 Demo
│ ├── GroupByKeyDemo.scala
│ ├── MyPartitioner.scala
│ ├── RddCreateDemo.scala
│ └── RepartitionVsCoalesce.scala
├── src/main/scala/org/exercises/
│ ├── exercises1/ # 第 1 课:Spark 入门
│ │ ├── demo/ # 演示 Demo1~5
│ │ └── exercises/Exercises1..5.scala # 课后 5 题(题目以中文注释形式嵌入文件头)
│ ├── exercises2/ # 第 2 课:RDD 算子(map / filter / flatMap / reduce / foreach)
│ └── exercises3/ # 第 3 课:PairRDD / reduceByKey / WordCount
└── src/main/resources/
├── create_table.sql # MySQL:Top10 平均评分电影 + 类别平均评分
├── log4j.properties
└── word.txt
```
## 快速上手
### 1. 准备环境
- **JDK 8**(`pom.xml` 已锁定 `maven.compiler.source/target=8`,高版本会编译失败)
- **Maven 3.6+**(仓库根目录留有 `.mvn/`,但还没生成 `mvnw`,自行安装一个 `mvn` 到 `PATH` 即可)
- 一台能跑 `local` / `local[2]` 模式的机器即可,**不需要真正的 Spark 集群**
### 2. 编译与打包
```bash
# 1) 拉依赖
mvn -DskipTests dependency:resolve
# 2) 编译(Scala + Java 同时)
mvn compile
# 3) 跑测试(当前 src/test/ 仍为空,等价于空跑)
mvn test
# 4) 打 fat jar(含 Spark / Hadoop / MySQL 等所有依赖)
mvn package
# 5) 产出路径
ls target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar
```
### 3. 跑一个 Scala 入口
两种方式二选一:
**方式 A:IDE 直跑**。在 IntelliJ IDEA 里直接打开 `pom.xml`,把以下任一对象作为 `main` 入口运行:
- `org.example.App` — `local[2]` 模式读 `src/main/resources/word.txt`,做一次 `count + filter + flatMap → reduceByKey` 的 WordCount
- `org.exercises.exercises3.exercises.Exercises5` — 纯数据集合版 WordCount(输出 `hello=3, spark=3, scala=1, is=1, powerful=1`)
**方式 B:命令行跑 fat jar**。
```bash
java -cp target/spark_project-1.0-SNAPSHOT-jar-with-dependencies.jar \
org.example.App
```
> 默认 `pom.xml` 没配 `exec-maven-plugin`,所以 `mvn exec:java` 用不了,要么走方式 A,要么上 fat jar。
## 三套练习索引
### `exercises1` — 第 1 课:Spark 是什么,以及第一个 Spark 程序
源:`src/main/scala/org/exercises/exercises1/`
主题:`SparkConf` / `SparkContext` 创建、并行化集合、读取外部文件。
代表题:
| 编号 | 题目要点 |
| ----- | ------------------------------------------------- |
| Ex 1 | 搭一个 `SparkContext`,`setMaster("local")` |
| Ex 2 | 从本地/集合源构造 RDD |
| Ex 3 | 基础转换算子 |
| Ex 4 | 触发动作算子 |
| Ex 5 | 综合:第一个本地 WordCount |
### `exercises2` — 第 2 课:RDD 常用算子
源:`src/main/scala/org/exercises/exercises2/`
主题:单值 RDD 的转换与动作。
| 编号 | 算子 |
| ----- | ------------ |
| Ex 1 | `map` |
| Ex 2 | `filter` |
| Ex 3 | `flatMap` |
| Ex 4 | `reduce` |
| Ex 5 | `foreach` |
### `exercises3` — 第 3 课:PairRDD 与 reduceByKey
源:`src/main/scala/org/exercises/exercises3/`
主题:键值对 RDD 常用算子与正式 WordCount。
| 编号 | 算子 / 内容 |
| ----- | -------------------------------------------------------- |
| Ex 5 | 正式练 WordCount:`flatMap → map → reduceByKey → collect` |
> `exercises1/2/3/demo/` 目录下还有 5 个对应演示,可在写练习前打开当作参考实现。
## MySQL 结果表
`src/main/resources/create_table.sql` 里两张表是后续评分分析的目标输出:
| 表名 | 主用途 |
| -------------------------- | ---------------------------------- |
| `top_ten_avg_ratings` | TopN 平均评分电影(`movie_id` 唯一) |
| `genres_average_rating` | 类型平均评分(`genres` 唯一) |
依赖侧(`pom.xml`)已经预备好:
- `mysql-connector-java` 8.0.28
- `HikariCP` 4.0.3
- `commons-dbutils` 1.6
下一步只要写真实的 Spark SQL / DataFrame → JDBC 写入逻辑即可。使用前请在 MySQL 里先执行 `create_table.sql`。
## 提交规范
仓库已有 6 条 commit,主题风格统一为**简体中文 + 简短摘要**:
```
feat:ChatGPT 第 1 课:Spark 是什么,以及第一个 Spark 程序
feat:ChatGPT 第 2 课:RDD 常用算子
feat:ChatGPT 第 3 课:PairRDD 与 reduceByKey
线下课:RDD的创建、RDD的操作、RDD重分区
feat:首次提交
```
继续沿用 `feat:<主题>` 形式,**中文一句话主题**,变更保持原子(新题 / 新课一个 commit)。默认分支 `main`,从 `main` 拉 feature 分支再合,禁止直接 push。
## 安全约定
- `target/`、`.idea/`、`*.iml` 等构建/IDE 产物已在 `.gitignore`
- **MySQL / Hadoop 凭据**一律外部化(环境变量或 `*.local.properties`,并加入 `.gitignore`),不要写进 `src/main/resources/`
- 不要把含个人 token 的 fat jar 提交到仓库
## 下一步
- [ ] `src/test/` 仍为空,按练习补 JUnit 3 测试用例
- [ ] 把 Spark SQL/DataFrame 的分析结果真正写回 `top_ten_avg_ratings`、`genres_average_rating`
- [ ] 加一份 `.mvn/wrapper/maven-wrapper.properties` 让团队对齐 Maven 版本