这是我参与「第四届青训营 」笔记创作活动的的第5天,学习了【Spark 原理与实践】的内容,重点是了解了Spark的计算模型、执行流程和sparkSQL优化。
spark
spark是一个对数据工程、数据科学和机器学习的支持单机或集群的多语言引擎。
大数据技术栈
graph TD
A[hadoop/map reduce] --> B[spark /内存存储]
特性
- 统一引擎
- 多语言
- 多数据源
- 丰富API/算子 DataFrame另外存储数据结构
架构
spark core
RDD(Resilient Distributed Datasets)
定义:容错的,可以并行执行的分布式数据处理模型
读、计算等操作都被当成一个RDD来看
五要素
-
partitions
-
Compute A function for computing each split/partition
-
Dependencies RDDD 之间有依赖关系
-
Partitioner for key-value RDDs
-
Preferred locations 数据本地计算,减少shuffle时间
算子类型
- Transform:生成新RDD
- Action:触发算子提交
RDD依赖
- 窄依赖:1对1
- 宽依赖:多对多,会产生shuffle
执行过程
- action算子提交job
- 根据依赖生成DAG,切分stage,为每个stage生成并提交taskset
- Task调度器将task调度到executor上执行
内存管理
1 storage 内存
2 execution 内存
两种内存可互相借用
sparkSQL
catalyst优化器
SQL analysis + logical optimization + physical plan
RBO实现
RuleExecutor 里边有很多batch(代表一套规则),对语法树进行遍历和模式匹配,形成最优的规则
batch分为两类,Once只执行一次;FixedPoint 重复执行直到计划不再改变
AQE(Adaptive Query Execution)
解决CBO统计数据旧,导致的优化偏差问题;一边执行一边优化
partition合并
问题: partition的数量对开销有影响
实现:先设置大的,随后运行过程中动态合并
runtime filter
减少大表扫描,减少数据量
skew join
大partition拆分多个task
codegen
- expression
将虚函数调用压平到函数内部 - wholestagecodegen
同stage的多算子压平到同一个函数内部
火山模型
自顶向下调用next接口,数据被从底层拉取上来