加载中...
内存管理机制
发表于:2022-02-26 | 分类: 《Apache Spark设计与实现》读书笔记
字数统计: 575 | 阅读时长: 1分钟 | 阅读量:

内存管理机制

一方面,在Spark执行过程中,需要在内存中处理大量数据。另一方面,数据缓存机制也会在内存中缓存大量数据避免重复计算。所以,需要设计一个内存管理机制

内存消耗的来源

首先我们要梳理一下spark中内存消耗的来源:

  • 第一个就是用户代码里使用到的数据和数据结构
  • 第二个是Shuffle Write时使用AppendOnlyMap来在线聚合,消耗内存;以及Shuffle Read获取数据时会创建buffer以及聚合排序使用ExternalAppendOnlyMap,消耗内存
  • 第三个就是数据缓存

Spark内存管理模型

为了管理内存,我们需要思考如何设计一个内存管理模型,很显然,要么静态内存管理,要么动态内存管理

静态内存管理模型

实际上Spark1.6以前用的就是这种,把内存空间分成三份:

  • 用户代码空间占20%,框架执行空间(管理Shuffle机制数据)占20%,数据缓存空间占60%

缺点也很明显,很容易内存浪费和内存溢出

统一内存管理模型

也就是动态内存管理了,在静态内存管理的基础上,在运行时动态调整内存比例,看下面这张图

从上到下依次来看:

  • 首先是物理执行计划通过任务调度,把task分配到节点的Executor上执行,task可以共享Executor JVM的内存空间
  • 重点来看Executor JVM的内存空间,包含了堆内内存和堆外内存。
    • 堆内内存分成三个部分,框架内存空间、用户代码空间和系统保留空间
    • 框架执行和数据缓存共享框架内存空间,缓存空间不够用了可以占到整个框架内存空间,然后再还回来。框架执行最多只能占到整个框架内存的一半,且用了就不会再借给缓存空间了
    • 用户代码空间不够用就占框架内存空间,还不够用就OOM
    • 堆外内存用于框架执行和数据缓存,主要存序列化对象,并且不会自动GC,需要手动释放

上一篇:
Spark资源参数调优
下一篇:
错误容忍机制
本文目录
本文目录