码迷,mamicode.com
首页 > 其他好文 > 详细

Spark内存管理模型

时间:2020-05-24 23:52:11      阅读:70      评论:0      收藏:0      [点我收藏+]

标签:兼容性   res   空间不足   转移   参数   管理包   删除   legacy   mem   

一般来说,一个spark程序包含两种 JVM 程序,Dirver 和 Executor。Dirver 是主要的控制程序,负责创建 context,提交任务,
那 job 转换为 task 并且协调 task 在 executor 中的执行。Executor 主要是负责执行计算任务并且将结果返回给 Driver。
因为 Driver 的内存管理相对简单,它与普通的 JVM 程序差别并不大。主要关注于 Executor 的内存结构。


堆内(On-Heap) 内存 和 堆外(Off-Heap)内存

Executor 作为一个 JVM 程序,其结构也是基于 JVM的。而 JVM 的内存管理包含两部分:
On-Heap 内存:对象分配基于 JVM 并且会 GC 的控制。
Off-Heap 内存:对象经过序列化后分配在内存外部,由应用程序管理。并且不受 GC 控制。
这一部分的内存结构可以避免频繁的 GC ,但是缺点是必须手动的控制内存的管理和释放逻辑。

一般情况下,对象的读写速度排序是:
on-heap > off-heap > disk

内存分配

在Spark中,支持两种内存管理模式:静态内存管理器和统一内存管理器。

Spark提供了一个统一的接口 MemoryManager 来管理存储和使用内存。同一 executor 中的任务调用该接口以申请或释放内存。
在实现 MemoryManage r时,它默认在Spark 1.6之前使用StaticMemory管理,而默认方法已在Spark 1.6之后更改为 UnifiedMemoryManager。
在Spark 1.6+中,可以通过spark.memory.useLegacyMode参数启用静态内存管理。

静态内存管理器 Static Memory Manager (逐渐被淘汰)

在静态内存管理器机制下,Storage ,EXecution 和其他内存的大小在Spark应用程序运行期间是固定的,但是用户可以在应用程序启动之前对其进行配置。
尽管已逐渐取消了这种分配方法,但出于兼容性原因,Spark仍然保留。

这里主要讨论静态内存管理器的弊端:静态内存管理器机制实现起来比较简单,但是如果用户不熟悉Spark的存储机制,或者不根据特定的数据大小进行相应的配置。
在执行计算任务时,很容易导致其中一个 Storage 内存和 Executor 内存剩余大量空间,而另一个内存首先被填满,因此必须删除旧内容以用于新内容。

统一内存管理器 Unified Memory Manager
Spark 1.6之后引入了统一内存管理器机制。 统一内存管理器和静态内存管理器之间的区别在于,在统一内存管理器机制下,Storage 内存和 Executor 内存共享一个内存区域,
并且两者都可以占据彼此的空闲区域。
On-head model
默认情况下,Spark仅使用堆上内存。 当Spark Application启动时,堆内存由–executor-memory或spark.executor.memory参数配置。 在Executor中运行的并发任务共享JVM的堆上内存。

Executor 中的堆上内存区域可以大致分为以下四个块:

Storage Memory:主要用于存储Spark缓存数据,如RDD缓存,Broadcast变量,Unroll数据等。
Execution Memory:主要用于在Shuffle,Join,Sort,Aggregation等计算过程中存储临时数据。
User Memory:它主要用于存储RDD转换操作所需的数据,例如RDD依赖项的信息。
Reserved Memory:内存是为系统保留的,用于存储Spark的内部对象。

技术图片

 

 

 

Off-heap model

Spark 1.6开始引入堆外内存(SPARK-11389)。默认情况下,堆外内存是禁用的,但是我们可以通过spark.memory.offHeap.enabled 参数启用它 ,并通过spark.memory.offHeap.size 参数设置内存大小 。

与堆上内存相比,堆外内存的模型相对简单,仅包括 Storage 内存和 Executor 内存,其分布如下图所示:

技术图片

 

 如果启用了堆外内存,则 Executor 中将同时有堆上内存和堆外内存。此时,Executor 中的 Execution 内存是堆内部的 Execution 内存与堆外部的 Execution 内存之和。Storage 内存也是如此。下图显示了Spark堆内部和外部的堆上和堆外内存。

技术图片

 

 

动态占用机制
  • 提交程序后,将根据该spark.memory.storageFraction 参数设置 Storage 存储区和 Execution 存储区 。
  • 当程序运行时,如果双方的空间不足(存储空间不足以放置一个完整的块),它将根据LRU存储到磁盘;如果其中一个空间不足,而另一个空间可用,则它将借用另一个空间。
  • Storage 占用对方的内存,然后将占用的部分转移到硬盘上,然后“返还”借来的空间。
  • Execution 占用了对方的内存,在当前实现中无法“返还”借用的空间。因为由Shuffle进程生成的文件将在以后使用,并且以后不必再使用Cache中的数据,所以返回内存可能会导致严重的性能下降。

https://xinze.fun/2020/01/12/%E7%90%86%E8%A7%A3spark%E7%9A%84%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86%E6%A8%A1%E5%9E%8B/

Spark内存管理模型

标签:兼容性   res   空间不足   转移   参数   管理包   删除   legacy   mem   

原文地址:https://www.cnblogs.com/songyuejie/p/12953428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!