# 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: