这是我参与「第四届青训营 」笔记创作活动的第5天
Lect05. Spark 原理与实践
01. 大数据处理引擎Spark介绍
1.1 大数据处理技术栈
数据
计算算子代价
计算执行计划代价
执行计划枚举
1.2 常见大数据处理链路
1.3 开源大数据处理引擎
批式计算:hadoop Map Reduce、hive、Spark
流式计算
OLAP
1.4 什么是Spark?
Apache Spark™ is a multi-language engine for executing data engineering, data science, and machinelearning on single-node machines or clusters.
生态&特点:
支持多语言
- SparkCore:Spark的核心组件,任务调度、内存管理、错误恢复、与存储系统交互等模块。
- SparkSQL:操控结构化数据(查询hive、hBase),可查询丰富的数据源
- Spark Structured Streaming
- MLlib:机器学习库
1.5 特点:
-
多语言支持:
- SQL
- Java/Scala
- R
- Python
-
丰富的数据源:
- 内置DataSource
- 自定义DataSource
-
丰富的API/算子
- SparkCore--->RDD
- SparkSQL--->DataFrame
1.6 Spark运行架构&部署方式
标准master-slave架构
-
Cluster Manager:监控Worker Node,负责资源管理和调度,支持多种模式
-
Worker Node:从节点(Node Manager)启动Executor,Task
- Executor:实际执行任务
- Task:实时将状态返回给Driver
-
Driver Program:App manager,一个Java进程。将用户程序划分为不同的Stage,每一个Stage会有一组完全相同的Task
- 创建一个SparkContext:控制应用生命周期,连接到Cluster Manager
部署方式
- Spark Local Mode
- Spark Standalone Mode
- On YARN / K8S
02. SparkCore原理解析
2.1 SparkCore
2.2 什么是RDD
容错、并行处理的数据集,Spark中最基本的数据处理单元
特点:
- 并行
- 计算函数
- 依赖
- 分区
- 优先列表
- 内存中 缓存数据集
2.2.1 如何创建RDD
- 内置RDD
- 自定义RDD
2.2.2 RDD算子
两类RDD算子:
- Transform算子:生成一个新的RDD
- Action算子: 触发Job提交
2.2.3 RDD依赖
描述父子RDD之间的依赖关系
-
窄依赖:父RDD的每个partition至多对应一个子RDD分区
- NarrowDependency
- OneToOneDependency
- RangeDependency
- PruneDependency
-
宽依赖(会产生Shuffle):父RDD的每个partition都可能对应多个子RDD分区
- ShuffleDependency
检查点checkpoint
2.5 Shuffle
2.5.1 SortShuffleManager
每个MapTask生成一个Shuffle数据data文件和一个Index文件
2.5.2 External Shuffle Service
Shuffle write的文件被NodeManager中的Shuffle Service托管,供后续ReduceTask进行Shuffle Fetcb,如果Executor空闲,DRA可以进行回收
03. SparkSQL原理解析
3.1 Catalyst优化器
最主要部分:Optimize
-
RBO
-
RuleExecutor
-
Batch执行策略:
- Once:只执行一次
- FixedPoint:重复执行,直到plan不再改变,或者执行达到固定次数(默认100次)
-
谓词下推
-
-
CBO
-
Filter Join
-
正确的join类型
- Broadcast Hash Join,BHJ
- Shuffle Hash Join,SHJ
- Sort Merge Join,SMJ
-
改变join顺序
-
3.2 Adaptive Query Execution(AQE),自适应查询
-
Partition合并 (Coalescing Shuffle Partitions)
-
动态切换join策略(Switching Join Strategies)
- Catalyst Optimizer优化阶段,算子的statistics估算不准确,生成的执行计划并不是最优
- AQE运行过程中动态获取准确Join的leftChild/rightChild的实际大小,将SMJ转换为BHJ
-
优化数据倾斜Join(Optimizing Skew Joins)
- AQE根据MapStatus信息自动检测是否有倾斜,将大的partition拆分成多个Task进行Join
3.5 Codegen - Expression
表达式:将表达式中的大量虚函数调用压平到一个函数内部,类似手写代码
简单拼成java代码
3.5 Codegen - WholeStageCodegen
算子:火山模型
算子之间大量的虚函数调用,开销大
——将同一个Stage中的多个算子压平到一个函数内部进行执行
04. 业界挑战与实践
4.1 Shuffle稳定性问题
在大规模作业下,开源ExternalShuffleService(ESS)的实现机制容易带来大量随机读导致的磁盘IOPS瓶颈、 Fetch 请求积压等问题,进而导致运算过程中经常会出现 Stage重算甚至作业失败,继而引起资源使用的恶性循环,严重影响SLA。
4.2 SQL执行性能问题
问题:压榨CPU资源
- CPU流水线/分支预测乱序执行/SIMD/CPU缓存友好l ...
- Vectorized /Codegen ?
- C++ / Java ?
4.3 参数推荐/作业推荐
- Spark参数很多,资源类/Shuffle/Join/Aggl . ..调参难度大
- 参数不合理的作业,对资源利用率/Shuffle稳定性/性能有非常大影响
- 同时,线上作业失败/运行慢,用户排查难度大
解决方法:自动参数推荐/作业诊断