Spark 原理与实践 | 青训营笔记

101 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第5天

1. 大数据处理引擎Spark介绍

1.1. 大数据处理技术栈

image.png

1.2. 常见大数据处理链路

image.png

1.3. 开源大数据处理引擎

image.png

1.4. 什么是Spark

介绍:

image.png

主要特性:

image.png

1.4. Spark版本演进

image.png

1.4. Spark生态 & 特点

  • 统一引擎,支持多种分布式场景
  • 多语言支持
  • 可读写丰富数据源
  • 丰富灵活的API/算子
  • 支持 K8S/YARN/Mesos 资源调度

image.png

1.5. Spark特点

1.5.1. 多语言支持

image.png

1.5.2. 丰富数据源

内置 DataSource

  • Text
  • Parquet/ORC
  • JSON/CSV
  • JDBC

自定义 DataSource

  • 实现 DataSource V1/V2 API
  • Hbase/Mango/ElasticSearch

1.5.3. 丰富的API/算子

image.png

image.png

1.6. Spark 运行架构 & 部署方式

1.6.1. Spark Local Mode

本地测试/单进程多线程模式

1.6.2. Spark Standalone Mode

需要启动Spark的Standalone的Master/Worker

1.6.3. on YARN/K8S

依赖外部资源调度器(YARN/K8S)

1.7. Spark包下载编译

编译:

image.png

下载:

image.png

1.8. 包概览

image.png

image.png

1.9. Spark提交命令

环境变量:

image.png

Spark shell

image.png

Spark SQL

image.png

pyspark

image.png

1.10 提交一个简单的任务

SparkPi Scala

image.png

编译成jar包后用spark-submit提交

image.png

1.11. Spark UI

image.png

1.12. Spark性能benchmark

image.png

2. SparkCore原理解析

2.1. SparkCore

image.png

2.2. 什么是RDD

RDD:弹性分布式数据集

描述RDD的五要素

image.png

2.2.1. 如何创建RDD

内置RDD:

image.png

自定义RDD

image.png

2.2.2. RDD算子

两类RDD算子

  • Transform算子:生成一个新的RDD

map/filter/flatmap/groupByKey/reduceByKey/...

image.png

  • Action算子:触发Job提交

collect/count/take/saveAsTextFile/...

image.png

2.2.3. RDD依赖

RDD依赖:描述RDD父子之间的依赖关系

  • 窄依赖:父RDD的每个partition至多对应一个子RDD分区
    • NarrowDependency
    • OneToOncDependency
    • RangeDependency
    • PruneDependency
  • 宽依赖(会产生Shuffle):父RDD的每个partitio都可能对应多个子RDD分区
    • ShuffleDependency

image.png

image.png

2.2.4. RDD执行过程

  • Job:RDD action算子触发
  • Stage:依据宽依赖划分
  • Task:Stage内执行单个partition任务

image.png

2.3. Scheduler

image.png

2.4. MemoryManagement

  • Executor 内存主要有两类:Storage、Execution
  • UndefinedMemoryManagement 统一管理Storage/Execution内存
  • Storage、Execution内存使用时动态调整,可以互相借用
  • 当Storage空闲,Execution可以借用Storage内存
  • 可以减少spill等操作,Execution使用的内存不可以被Storage驱逐
  • 当Execution空闲,Storage可以借用Execution内存
  • 当Execution需要内存时,可以驱逐被Storage借用的内存,直到spark.memory.storageFraction边界

image.png

UndefinedMemoryManagement统一管理多个并发Task内存分配

每个Task获取的内存区间是:1/(2*N) ~ 1/N N为当前Execution中并发运行的Task数量

image.png

2.5. Shuffle

image.png

每个MapTask生成一个Shuffle文件和一个Index文件
dataFile中的数据按照partitionId进行排序

同一个partitionId的数据聚集在一起

indexFile保存了所有partitionId在dataFile中的位置信息

方便后续Reduce Task能Fetch到对应partitionId的数据

image.png

image.png

shuffle write的文件被Node Manager中的Shuffle Service托管,供后续Reduce Task进行Shuffle Fetch,如果Executor空闲,DRA可以进行回收

image.png

3. SparkSQL原理解析

image.png

3.1. Catalyst 优化器

image.png

3.1.1. Catalyst 优化器 - RBO

image.png

image.png

3.1.2. Catalyst 优化器 - CBO

image.png

3.2. Adaptive Query Execution(AQE)

image.png

3.2.1. AQE - Coalescing Shuffle Partitions

image.png

3.2.2. AQE - Switching Join Strategies

image.png

3.2.3. AQE - Optimizing Skew Joins

image.png

3.3. Runtime Filter

image.png

3.4. Bloom Runtime Filter

image.png

3.5. Codegen - Expression

image.png

3.5. Codegen - WholeStageCodegen

image.png

image.png

4. 业界挑战与实践

4.1. Shuffle 稳定性问题

image.png

4.1. Shuffle 稳定性解决方案

image.png

4.2. SQL 执行性能问题

image.png

4.2 SQL 执行性能解决方案

image.png

4.3. 参数推荐/作业诊断

image.png