文章目录
- 概述
- 1. 新旧内存管理器交替
- 2. 内存管理相关组件
- MemoryManager
- 内存划分
- 系列文章
概述
Spark作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中占据着非常重要的角色。理解Spark内存管理的基本原理,有助于更好地开发Spark应用程序和进行性能调优。本系列文章,旨在梳理出Spark内存管理的脉络。本文中的源码基于Spark 2.4.+版本。阅读本文需要读者有一定的Spark和Java基础,了解RDD、Shuffle、JVM等相关概念。
1. 新旧内存管理器交替
在Spark1.6之前的版本中,采用的是StaticMemoryManager作为唯一的内存管理器,而StaticMemoryManager中,Storage Memory和Execution Memory的大小是固定的。这会导致很多的闲置浪费。
在Spark1.6之后的版本,则采用了新的内存管理器–UnifiedMemoryManager。得益于它的动态占用机制,内存的浪费缺陷,得到了很好的优化。
不过,无论是StaticMemoryManager还是UnifiedMemoryManager,均是继承自接口MemoryManager。
2. 内存管理相关组件
组件 | 说明 |
---|---|
| 内存管理器的抽象类,将内存主要划分为Storage、Execution和other三类(还有一个系统预留内存,先不管)。 |
| 不是MemoryManager的子类,而是在内部定义了一个MemoryManager,用于管理那个Task的内存。 TaskMemoryManager在Task.run()时创建 |
| spark 1.6之前的静态内存管理器,通过配置 启用,默认关闭 |
| spark 1.6新加入的统一资源管理器,默认使用。优势在于其动态占用机制 |
| 由BlockManager创建。主要作用为管理 ,即管理storage这部分内存 |
| 用于记录storage、execution内存的使用情况,对应子类分别为StorageMemoryPool、ExecutionMemoryPool |
MemoryManager
内存管理器的抽象类,将内存主要划分为Storage、Execution、other、系统预留内存四类(Storage内部还有unroll)。每一个 JVM 会产生一个 MemoryManager 来负责管理内存。
- MemoryManager 构造时,需要指定 onHeapStorageMemeory和 onHeapExecutionMemory 的参数。
- MemoryManager 构造时,还会创建 StorageMemoryPool 和 ExecutionMemoryPool 对象,用来管理 Storage 和 Execution 的内存分配。
- StorageMemoryPool中有一个memoryUsed记录Storage已使用的内存
- ExecutionMemoryPool中有一个HashMap 来存储每个 Task 的内存使用量,相加即可得到Execution已使用内存。
- MemoryManager会被BlockManager管理。而MemoryStore则会被BlockManager创建,MemoryStore是BlockManager用于与MemoryManager交互的媒介,完成内存操作,完成。(参见Spark存储管理之Storage模块解析中 1.2.1 BlockManager和BlockManagerMaster的创建 和 1.2.2 MemoryStore和DiskStore的创建)。 从上图可以看出来,MemoryManager管理堆内、堆外的内存,堆内内存是必须的。查看其Outline: 说明:
- 从源码中的类分析可以看出来,MemoryMnager只是作为一个接口提供了内存的抽象的申请(acquire)释放(Release)方法,具体的实现放在子类中。
- Memory主要管理Storage和Execution内存。申请和释放主要涉及Storage、Execution、unRoll这三部分。
- MemoryManager还引入了Tungsten内存管理模式。
查看子类继承关系:
内存划分
这里只是列出了堆内内存的划分,具体的请参考Spark内存管理之堆内/堆外内存原理详解。
分区 | 说明 |
---|---|
| 主要用于存放 Shuffle、Join、Sort、Aggregation 等计算过程中的临时数据 |
| 主要用于存储 spark 的 cache 数据,例如RDD的缓存、unroll数据。
: 是指 BlockManager收到iterator形式的数据,最终存放到内存的过程。Unroll占用的是Storage的内存 |
| 主要用于存储 RDD 转换操作所需要的数据,例如 RDD 依赖等信息 |
| 系统预留内存,会用来存储Spark内部对象,属于系统内存,用户接触不到 |
上面各部分所占比例由内存管理器实现类
StaticMemoryManager
、
UnifiedMemoryManager
确定
系列文章
- Spark内存管理概述
- Spark内存管理之堆内/堆外内存原理详解
- Spark内存管理之存储内存管理
- Spark内存管理之执行内存管理
- Spark存储管理之Storage模块解析