目 录
第1章 Spark简介 1
1.1 Spark概念及其特点 1
1.2 Spark技术生态系统 2
1.3 Spark运行模式 4
1.4 Spark执行流程 8
1.5 Spark专有名词 9
1.6 本章小结 11
第2章 Spark集群环境部署 12
2.1 VM虚拟机安装 13
2.2 Ubuntu 22.04系统安装 19
2.3 Ubuntu 22.04网络配置 24
2.4 Ubuntu 22.04环境配置 28
2.5 ZooKeeper安装 33
2.6 Hadoop安装 35
2.6.1 下载并解压 35
2.6.2 配置系统环境变量 35
2.6.3 配置核心文件 36
2.6.4 分发Hadoop 40
2.6.5 启动和验证 40
2.7 Spark安装 47
2.7.1 下载和解压 47
2.7.2 配置系统环境变量 47
2.7.3 配置核心文件 47
2.7.4 分发Spark 48
2.7.5 Spark启动及UI界面查看 48
2.7.6 spark-shell启动验证 49
2.8 集群和代码下载 50
2.9 本章小结 52
第3章 Spark编程体验 54
3.1 Scala基础编程 54
3.1.1 基本语法 55
3.1.2 函数和方法 57
3.1.3 控制语句 59
3.1.4 函数式编程 62
3.1.5 类和对象 67
3.1.6 Scala异常处理 70
3.1.7 Trait(特征) 72
3.1.8 Scala文件I/O 73
3.1.9 Scala练习题 74
3.2 Spark创建项目 80
3.3 Spark程序编写与运行方法 90
3.4 本章小结 92
第4章 RDD深度解读 93
4.1 RDD的概念及特点 93
4.1.1 RDD的特点 94
4.1.2 RDD的算子分类 95
4.1.3 RDD创建方法 95
4.2 RDD的血缘和依赖 97
4.2.1 血缘与依赖的概念 98
4.2.2 Dependency依赖关系 98
4.3 RDD的Transformation算子 103
4.4 RDD的Action算子 122
4.5 RDD的特殊算子 129
4.5.1 cache和persist 129
4.5.2 checkpoint 131
4.6 RDD转换算子的惰性 133
4.6.1 Scala迭代器Iterator接口 133
4.6.2 Scala迭代器Lazy特性及原理 134
4.7 模拟Spark自定义RDD 135
4.8 Spark任务执行原理图解分析 138
4.8.1 WordCount程序元素分解 138
4.8.2 WordCount程序图解 139
4.8.3 Stage和Task的类型 142
4.9 案例:多种算子实现WordCount 143
4.9.1 map + reduceByKey 144
4.9.2 countByValue 145
4.9.3 aggregateByKey或foldByKey 146
4.9.4 groupByKey+map 147
4.9.5 Scala原生实现wordCount 148
4.9.6 combineByKey 149
4.10 本章小结 150
第5章 RDD的Shuffle详解 151
5.1 Shuffle的概念及历史 151
5.1.1 Shuffle的概念 151
5.1.2 Shuffle演进的历史 152
5.2 Shuffle的验证及复用性 153
5.2.1 案例:reduceByKey一定会Shuffle吗 153
5.2.2 案例:join操作一定会触发Shuffle吗 155
5.2.3 Shuffle数据的复用实验 156
5.3 HashShuffleManager 160
5.3.1 HashShuffleManager优化前 160
5.3.2 HashShuffleManager优化后 161
5.4 SortShuffleManager 162
5.4.1 普通运行机制 163
5.4.2 Bypass运行机制 164
5.5 本章小结 164
第6章 Spark共享变量 166
6.1 广播变量 166
6.1.1 广播变量的使用场景 166
6.1.2 广播变量的实现原理 168
6.1.3 案例:两个集合进行结合 168
6.2 累加器 170
6.2.1 累加器使用场景 170
6.2.2 累加器实现原理 171
6.2.3 案例:自定义累加器 173
6.2.4 案例:不使用累加器的方案 174
6.2.5 案例:使用累加器的方法 175
6.3 本章小结 176
第7章 Spark序列化和线程安全 177
7.1 Spark序列化 177
7.1.1 序列化问题的场景 177
7.1.2 数据Bean未实现序列化接口 178
7.1.3 函数闭包及其示例 179
7.2 Task线程安全 191
7.2.1 线程不安全及其解决方案 191
7.2.2 避免线程不安全的示例 192
7.3 本章小结 195
第8章 Spark内存管理机制 196
8.1 内存管理概述 196
8.2 堆内内存和堆外内存的区别 197
8.3 堆内内存 198
8.4 堆外内存 201
8.5 本章小结 204
第9章 Spark SQL简介 205
9.1 Spark SQL的定义和特性 205
9.2 Spark SQL编程抽象 206
9.3 Spark SQL快速体验 207
9.3.1 程序使用示例 208
9.3.2 命令行使用示例 209
9.3.3 新的编程入口SparkSession 211
9.4 本章小结 212
第10章 Spark SQL抽象编程详解 213
10.1 DataFrame创建 213
10.1.1 使用RDD创建DataFrame 214
10.1.2 从结构化文件创建DataFrame 220
10.1.3 外部存储服务创建DataFrame 224
10.2 DataFrame运算 230
10.2.1 SQL风格操作 230
10.2.2 DSL风格API(TableApi)语法 230
10.3 DataFrame输出 236
10.3.1 输出控制台 236
10.3.2 输出文件 236
10.3.3 输出到RDBMS 237
10.3.4 输出到Hive 237
10.3.5 DataFrame输出时的分区操作 238
10.4 RDD代码和SQL代码混合编程 240
10.4.1 Dataset和DataFrame的区别及取数 241
10.4.2 由RDD创建DataFrame 246
10.4.3 由RDD创建Dataset 256
10.5 RDD、Dataset与DataFrame的互相转换 261
10.6 本章小结 262
第11章 Spark SQL自定义函数 263
11.1 用户自定义函数UDF 263
11.1.1 UDF函数的概念及其特点 263
11.1.2 UDF案例1:字符串处理 264
11.1.3 UDF案例2:GEOHASH算法 265
11.1.4 UDF案例3:余弦相似度算法 269
11.1.5 UDF注意事项 271
11.2 用户自定义聚合函数UDAF 272
11.2.1 UDAF的编程模板 272
11.2.2 UDAF原理讲解 273
11.2.3 弱类型用户自定义聚合函数 274
11.2.4 强类型用户自定义聚合函数 276
11.2.5 UDAF注意事项 279
11.3 本章小结 279
第12章 Spark SQL源码解读 280
12.1 Spark SQL的执行过程 280
12.2 元数据管理器SessionCatalog 281
12.3 SQL解析成逻辑执行计划 281
12.4 Analyzer绑定逻辑计划 284
12.5 Optimizer优化逻辑计划 286
12.5.1 谓词下推 290
12.5.2 列裁剪 290
12.5.3 常量替换 291
12.5.4 常量累加 292
12.6 使用SparkPlanner生成物理计划 293
12.7 从物理执行计划获取inputRdd执行 296
12.8 本章小结 296
第13章 Spark性能调优 297
13.1 Spark常规性能调优 297
13.1.1 常规性能调优一:最优资源配置 297
13.1.2 常规性能调优二:RDD优化 298
13.1.3 常规性能调优三:并行度调节 299
13.1.4 常规性能调优四:广播大变量 299
13.1.5 常规性能调优五:Kryo序列化 300
13.1.6 常规性能调优六:调节本地化等待时长 300
13.1.7 常规性能调优七:ShuGle调优 301
13.1.8 常规性能调优八:JVM调优 302
13.2 Spark开发原则优化 304
13.2.1 开发原则一:避免创建重复的RDD 304
13.2.2 开发原则二:避免创建重复的DataFrame 305
13.2.3 开发原则三:尽可能复用同一个RDD 305
13.2.4 开发原则四:避免重复性的SQL查询,对DataFrame复用 306
13.2.5 开发原则五:注意数据类型的使用 307
13.2.6 开发原则六:写出高质量的SQL 308
13.3 Spark调优方法 310
13.3.1 优化数据结构 310
13.3.2 使用缓存(Cache) 310
13.3.3 对配置属性进行调优 312
13.3.4 合理使用广播 314
13.3.5 尽量避免使用Shuffle算子 315
13.3.6 使用map-side预聚合的Shuffle操作 316
13.3.7 使用高性能算子 317
13.3.8 尽量在一次调用中处理一个分区的数据 318
13.3.9 对数据进行序列化 318
13.4 Spark数据倾斜调优 319
13.4.1 调整分区数目 319
13.4.2 去除多余的数据 320
13.4.3 使用广播将Reduce Join转换为Map Join 320
13.4.4 将key进行拆分,大数据转换为小数据 321
13.4.5 数据倾斜定位和解决 322
13.5 本章小结 327
第14章 Spark实战案例 328
14.1 Spark Core电影数据分析 328
14.1.1 表格及数据样例 329
14.1.2 连续登录超过3天的用户DSL风格 329
14.1.3 连续登录超过3天的用户SQL风格 330
14.1.4 电影统计DSL风格 332
14.1.5 电影统计SQL风格 333
14.1.6 电影统计运行结果 336
14.2 Spark Core日志数据分析 337
14.2.1 前期准备 338
14.2.2 统计PV和可视化 339
14.2.3 统计UV和可视化 342
14.2.4 统计TopN和可视化 346
14.3 Spark SQL电商数据分析 350
14.3.1 数据和表格说明 350
14.3.2 加载数据 351
14.3.3 计算每年的销售单数和销售总额 354
14.3.4 查询每年最大金额的订单及其金额 355
14.3.5 计算每年最畅销的货品 356
14.4 Spark SQL金融数据分析 358
14.4.1 数据准备 359
14.4.2 最大值和最小值 360
14.4.3 平均值 361
14.4.4 样本标准差和总体标准差 361
14.4.5 中位数 362
14.4.6 四分位数 364
14.5 本章小结 365
第15章 Spark面试题 366
15.1 Spark核心概念面试题 366
15.1.1 简述Spark是什么 366
15.1.2 简述Spark 3.0的特性 367
15.1.3 简述Spark生态系统有哪些组件 367
15.1.4 简述Spark的运行流程 368
15.1.5 简述Spark的主要功能与特性 368
15.1.6 简述Spark中RDD的Partitioner是如何决定的 369
15.1.7 简述SparkContext与SparkSession之间的区别是什么 369
15.1.8 简述Spark的几种运行模式 370
15.1.9 简述DAG为什么适合Spark 371
15.1.10 简述DAG如何划分Stage 371
15.2 Spark架构原理面试题 372
15.2.1 简述Spark SQL的执行原理 372
15.2.2 简述Spark SQL执行的流程 372
15.2.3 简述Spark相较于MapReduce的优势 373
15.2.4 简述RDD的宽依赖和窄依赖产生的原理 373
15.2.5 简述Stage的内部逻辑 374
15.2.6 简述为什么要根据宽依赖划分Stage 374
15.2.7 简述Spark on YARN运行过程 374
15.2.8 简述YARN Client与YARN Cluster的区别 375
15.2.9 简述Spark的YARN Cluster涉及的参数有哪些 376
15.2.10 简述Spark广播变量的实现和原理 376
15.3 Spark编程实践面试题 377
15.3.1 简述RDD是什么 377
15.3.2 简述对RDD机制的理解 377
15.3.3 简述RDD的宽依赖和窄依赖 378
15.3.4 简述RDD持久化原理是什么 378
15.3.5 简述RDD的容错机制 378
15.3.6 简述RDD的缓存级别 378
15.3.7 简述DAG中为什么要划分Stage 380
15.3.8 简述Spark SQL的数据倾斜解决方案 380
15.3.9 简述Spark SQL如何将数据写入Hive表 381
15.3.10 简述Spark SQL如何使用UDF 381
15.4 Spark性能调优面试题 382
15.4.1 简述Spark Checkpoint 382
15.4.2 简述Spark中Checkpoint和持久化机制的区别 383
15.4.3 简述Spark中的OOM问题 384
15.4.4 简述Spark程序执行时,如何修改默认Task执行个数 384
15.4.5 简述Spark Join操作的优化经验 385
15.4.6 简述Map Join的实现原理 386
15.4.7 简述Spark Shuffle在什么情况下会产生 387
15.4.8 简述Spark Shuffle会在哪些算子中出现 387
15.4.9 简述Spark中的Transform和Action 387
15.4.10 Spark的Job、Stage、Task如何划分 389
15.5 Spark实战应用面试题 389
15.5.1 简述Map和flatMap的区别 389
15.5.2 简述Map和mapPartition的区别 390
15.5.3 简述reduceByKey和groupByKey的区别 391
15.5.4 简述DataFrame的Cache和Persist的区别 391
15.5.5 简述reduceByKey和reduce的区别 392
15.5.6 简述Spark运行时并行度的设置 393
15.5.7 简述Spark解决了Hadoop的哪些问题 394
15.5.8 简述RDD、DataFrame、Dataset和DataStream的区别 395
15.5.9 简述Spark和MapReduce Shuffle的区别 395
15.5.10 简述RDD中reduceBykey与groupByKey哪个性能好 396
15.6 本章小结 396
