spark 内存模型以及存储
2020-02-28 本文已影响0人
loukey_j
spark 内存模型以及存储
参考原文https://www.cnblogs.com/qingyunzong/p/8955141.html
内存模型
堆内内存 & 堆外内存
- 堆内内存
- executor内task共享executor的堆内内存
- –executor-memory 参数控制
- JVM负责回收分配,spark只是记录内存对象是否被释放和估算对象的大小,但是真正的回收是JVM负责,所以 Spark 并不能准确记录实际可用的堆内内存
- 堆外内存
- worker内多个executor的多task共享堆外内存
- 配置
spark.memory.offHeap.enabled
参数启用,并由spark.memory.offHeap.size
参数设定堆外空间的大小- 因为存放的是二进制数据,是连续的空间,所以spark能精准的记录堆外内存的使用情况,回收不依赖JVM
- Spark 并不能准确记录实际可用的堆内内存
spark内存模型
- spark内存按功能分为,执行内存和存储内存
- 执行内存: 任务在执行 Shuffle 时占用的内存被规划为执行(Execution)内存
- 存储内存: 任务在缓存 RDD 数据和广播(Broadcast)数据时占用的内存被规划为存储(Storage)内 存
- 内存管理方式
- 静态内存管理
<img src="https://images2018.cnblogs.com/blog/1228818/201804/1228818-20180426212247280-1642194580.png" style="zoom:150%;" /> - 统一内存管理
<img src="https://images2018.cnblogs.com/blog/1228818/201804/1228818-20180426212726300-1935303266.png" style="zoom:150%;" /> - 静态内存管理 & 统一内存管理
- 内存分配不一样,详情见上图的对比
- 静态管理方式在任务启动后,存储内存和执行内存大小就固定了。当执行内存不足时不会申请存储内存用作执行(即使存储内存空闲);当存储内存不足时也不会申请执行内存来做存储(即使执行内存空闲)。
- 统一管理内存在任务启动后,当执行内存不足时可以借用存储内存,甚至把存储内存进行释放或者将数据落盘来空出内存给执行用。并且腾出给执行内存的空间不会还给存储内存;当执存储内存不足时可以借用执行内存,但是借用是暂时的必须归还。
- 凭借统一内存管理机制,Spark 在一定程度上提高了堆内和堆外内存资源的利用率,降低了开发者维护 Spark 内存的难度。
- 静态内存管理
RDD存储
- 存储的三个维度
- 存储位置:堆内内存,磁盘,堆外内存
- 是否序列化:
- 序列化后是内存占用连续的空间, 其占用的内存大小可直接计算 ,不序列化占用的内存是通过周期性地采样近似估算而得
- 序列化的过程是将对象转换为二进制字节流,本质上可以理解为将非连续空间的链式存储转化为连续空间或块存储,在访问时则需要进行序列化的逆过程——反序列化,将字节流转化为对象,序列化的方式可以节省存储空间,但增加了存储和读取时候的计算开销。
- 副本数:用于数据高可靠性保证,对内内存不能设置副本数
- RDD persist过程
- RDD是一个逻辑的概念,数据实际是对应一个个的分区数据
- 当对RDD有带 persist 或 cache 方法时,说明该RDD分区数据需要持久化
- 持久化工作会交给spark的 BlockManager进行处理,BlockManager 是一个Master/Slaver架构,Master运行在Dirver端,Slaver运行在 Executor 端。
- RDD的每一个分区经过处理后都对应一个 Block BlockId 的格式为 rdd_RDD-ID_PARTITION-ID 。
- Master 负责整个 Spark 应用程序的 Block 的元数据信息的管理和维护,而 Slave 需要将 Block 的更新等状态上报到 Master,同时接收 Master 的命令,例如新增或删除一个 RDD。