Spark应用程序执行时,Spark集群会启动Driver和Executor两种JVM进程,Driver端负责创建SparkContext上下文(通往集群的唯一通道),构建DAG, 创建Task并进行分发。而Executor负责Task的计算任务,并将最终的结果返回给Driver,同时需要为持久化的RDD提供存储。
Spark的Executor端的内存管理主要经历了两大阶段,在Spark1.6版本前使用的是静态内存管理,而在Spark1.6之后引入了统一内存管理。
Spark静态内存管理
Spark的静态内存管理:内存存储、执行内存和其他内存的大小在Spark应用程序执行期间均已按固定配额分配好,用户只能在提交任务的时候进行相关配置调整, 一旦任务提交资源申请好以后无法动态改变。
有关Spark静态内存的配额,请参考后面图表。
Spark统一内存管理
Spark1.6版本之后引入了统一内存管理,它与静态内存管理的区别在于存储内存和执行内存共享一块空间,可以相互借用。
在Spark1.6版本以后,统一内存管理的配额根据具体版本也有微小的不同,现以Spark 2.4.5进行配额讲解内存划分:
- 300M预留内存
- Task的运行内存:(总内存-300M预留内存)*0.4
- spark.memory.fraction: (总内存-300M预留内存)*0.6
- spark.memory.storageFraction:占用0.5, 即(总内存-300M预留内存)*0.6*0.5, 主要用来作为RDD的缓存和广播变量的存储
- 剩余的50%为shuffle的聚合内存
- a和b之间的内存可以相互动态借用,这样避免了资源的浪费,也避免了手工的设置。
- 在shuffle的文件寻址中的reduce task启动5个task拉取的数据,就是放到b这个shuffle聚合内存中。
Spark静态内存与统一内存图解
Spark内存管理.png
![1c7c2f8ddcf8b726a33008f8222a5bdf.png](https://i-blog.csdnimg.cn/blog_migrate/383766a9d501691f0698746b889fc407.jpeg)
Executor静态内存 vs 统一内存管理