SparkCore与3.0优化|青训营笔记

164 阅读3分钟

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

这一章我们主要学习spark core原理和spark3.0优化,阅读本文建议有一定的spark基础


首先我们学习spark的运行架构

这里默认下图所有的术语都了解

image.png spark的架构是主从模型:

  • Driver作为主节点,通过Main启动sparkcontext,控制整个应用的生命周期
  • Worker作为从节点负责启动executor和task的执行

那么简单介绍一下,一个应用被提交到执行中间经历了什么

  1. 首先用户main函数中创建sparkcontext,然后连接到clusterManager
  2. clusterManager会根据用户提交的参数,分配executor等资源
  3. 然后Driver根据代码生成逻辑计划,再转化成物理执行计划,划分多个stage,然后stage划分多个task发到executor去执行
  4. executor收到task以后,会准备好task需要的资源,在执行task中途会实时的汇报运行状态给driver
  5. driver会不断更新状态,和发task给executor执行,直到应用执行完毕

如何生成执行计划?


前面我们讲了应用提交后,Driver会根据代码生成logical plan,然后再生成physical plan

那么Driver具体是怎么操作的呢?

首先要学习,spark中RDD的两种依赖关系(宽依赖、窄依赖)


我们认为父RDD中的每个partition和子RDD中的partition是一对一的关系,则是窄依赖,否则是宽依赖

看下图就比较好理解了

image.png

接下来我们来学习Driver是如何生成逻辑计划和物理计划的呢?


  1. 首先RDD创建以后,sparkcontext就会这些RDD对象构建一个DAG**(logical plan)**
  2. 当RDD.action被触发之后,会提交给DAGScheduler,这个调度器会根据宽依赖划分stage
  3. 然后每个stage又会根据partition数量生成taskSet,提交给task调度器,调度器把task调度到work节点的executor去

image.png

Spark内存管理


下面我们讲一下Spark的内存管理机制,在运行spark任务之前,我们首先就要调整内存的参数设置

Excutor内存主要是Storage和Excution,这两个内存是可以动态调整的,他们的内存空间会互相借用

在设置这些参数的时候,比如说我代码中缓存和广播的数据比较多,那就调大Storage。Shuffle的量比较多就调大Execution

image.png

Spark SQL


我们写spark一般用sql写,那么sql是怎么被转化成spark代码,比如rdd的呢?

image.png 先解析成sql抽象语法树,然后遍历这个sql树上的节点,对元数据信息进行绑定,生成逻辑计划,然后经过RBO、CBO生成优化后的逻辑计划,然后再生成多个物理计划,然后再根据CBO选择物理计划转化成spark代码

sql的一生在第一节课也讲过了,这里就不再多讲了,我们这一章主要关注的是spark3.0在sql上的优化,这里仅简单介绍

AQE(Adaptive Query Execution)自适应查询


  • 动态合并shuffle分区
  • 动态调整join策略
  • 动态优化数据倾斜

RuntimeFilter


对参与join的表,提前进行分区裁剪或者数据过滤,然后再join

CodeGen

从提高cpu的利用率的角度来进行runtime优化