0


Spark内存模型

一.Spark内存

在执行 Spark 的应用程序时,Spark 集群会启动 Driver 和 Executor 两种JVM进程。

Driver 程序主要负责:

  • 创建 Spark上下文;
  • 提交 Spark作业(Job)并将 Job 转化为计算任务(Task)交给 Executor 计算;
  • 协调各个 Executor 进程间任务调度。

Executor 程序主要负责:

  • 在工作节点上执行具体的计算任务(Task),并将计算结果返回给 Driver;
  • 为需要持久化的 RDD 提供存储功能。

二.Executor内存管理

Executor 进程作为一个 JVM 进程,其内存管理建立在 JVM 的内存管理之上,整个大致包含两种方式:堆内内存和堆外内存。

一个Executor中包含多个task,一个 Executor 当中的所有 Task 是共享堆内内存的。一个 Work 中的多个 Executor 中的多个 Task 是共享堆外内存的。

默认的 Spark 是开启堆内内存的,配置参数:--executor-memory 指定的就是堆内内存大小。堆外内存默认不开启。

1.堆内内存管理

堆内内存的大小,由 Spark 应用程序启动时的

executormemory

或

spark.executor.memory

参数配置。

Executor 内运行的并发任务共享 JVM 堆内内存,这些任务在缓存 RDD 数据和广播(Broadcast)数据时占用的内存被规划为存储(Storage)内存,而这些任务在执行 Shuffle 时占用的内存被规划为执行(Execution)内存,剩余的部分不做特殊规划,那些 Spark 内部的对象实例,或者用户定义的 Spark 应用程序中的对象实例,均占用剩余的空间。不同的管理模式下,这三部分占用的空间大小各不相同

Spark 内存管理分为静态内存管理和统一内存管理,在 Spark 1.6 之前是采用的静态内存,之后的版本都是采用统一内存管理,与静态内存管理的区别在于 Storeage 内存和 Execution 内存共享统一块空间,可以动态占用对方的空闲区域。

Spark 统一内存模型:

  • Storage 内存:主要用于存储 Spark 的 cache 数据,例如 RDD 的 cache,Broadcast 变量,Unroll 数据等。需要注意,unrolled 的数据如果内存不够,会存储在 driver 端。
  • Execution 内存:用于存储 Spark task 执行过程中需要的对象,如 Shuffle、Join、Sort、Aggregation等计算过程中的临时数据。
  • User 内存:分配 Spark Memory 剩余的内存,用户可以根据需要使用,可以存储 RDD transformations 需要的数据结构。
  • Reserved 内存:这部分内存是预留给系统用的,固定不变。

动态占用机制

  • 在程序提交时,会根据spark.memory.storageFraction参数设置Storage内存区域和Execution内存区域。
  • 在程序运行时,如果双方的空间不不足(存储空间不足以放下一个完整的Block),则按照LRU规则存储到磁盘;如果己方空间不足而对方空间有空余,则借用对方的空间。
  • Storage占用对方内存,可将占用的部分转存到硬盘,然后”归还”借用的空间(Storage占用Execution内存,Execution需要使用被占用的内存时,会将存储在Execution中数据写入磁盘,归还占用的内存空间)。
  • Execution占用对方内存,目前的实现是无法让对方”归还”的。因为Shuffle过程产生的文件在后面一定会被使用到,而Cache在内存的数据不一定在后面使用,归还内存可能会导致性能严重下降。

内存指定参数

备注

spark.memory.fraction

设置统一内存占堆内内存的占比

spark.memory.fraction=0.6

spark.memory.storageFraction

设置Execution内存占堆内内存的占比

spark.memory.storageFraction=0.5

2.2 堆外内存

为了进一步优化内存的使用以及提高 Shuffle 时排序的效率,Spark 引入了堆外(Off-heap)内存,使之可以直接在工作节点的系统内存中开辟空间,存储经过序列化的二进制数据。堆外内存意味着把内存对象分配在 Java 虚拟机的堆以外的内存,这些内存直接受操作系统管理(而不是虚拟机)。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。

在默认情况下堆外内存并不启用,可通过配置 spark.memory.offHeap.enabled(true/false) 参数启用,并由spark.memory.offHeap.size(单位MB) 参数设定堆外空间的大小。除了没有 other 空间,堆外内存与堆内内存的划分方式相同如下图所示(以统一内存管理机制为例),所有运行中的并发任务共享存储内存和执行内存。

堆外内存分配参数:

spark.executor.memoryOverhead=3072 单位为MB

在spark 2.3 之前,参数命令为: spark.yarn.executor.memoryOverhead

spark.memory.offHeap.size 和spark.executor.memoryOverhead 都可以用于设置堆外内存,但实际是有差别的。

spark.memory.offHeap.size 真正作用于spark executor的堆外内存 spark.executor.memoryOverhead 作用于yarn,通知yarn使用堆外内存和使用内存的大小,相当于spark.memory.offHeap.size + spark.memory.offHeap.enabled,设置参数的大小并非实际使用内存大小

参考:

Spark 内存管理模型详解 - 走看看

Spark参数spark.executor.memoryOverhead与spark.memory.offHeap.size的区别_spark offheap 和overhead区别-CSDN博客


本文转载自: https://blog.csdn.net/jpfx6008/article/details/141111821
版权归原作者 Tom无敌宇宙猫 所有, 如有侵权,请联系我们删除。

“Spark内存模型”的评论:

还没有评论