【Spark】内存模型

本文深入探讨Spark内存模型,重点讲解Executor端的内存设计,包括堆内和堆外内存的划分,存储内存和执行内存的管理机制,以及如何避免内存溢出。通过对Executor内存的了解,有助于优化Spark应用性能和进行调优。
摘要由CSDN通过智能技术生成

一、简介

1、背景

Spark是基于内存的分布式计算引擎,内存模型与管理是核心知识点,理解它能更好地开发Spark应用和进行性能调优(解决作业GC耗时长问题—主要是Young GC)。

2、总体架构 & 运行流程

1
2

Spark整体运行流程:

  1. 构建运行环境。由Driver创建SparkContext,进行资源申请、任务分配与监控;
  2. 分配资源。SparkContext和Cluster Manager通信,为Executor申请资源,进行任务分配和监控,启动进程;
  3. 分解Stage,申请Task。 SparkContext构建DAG图,然后分解为Stage,每个Stage的TaskSet发给TaskScheduler。Executor向Driver申请Task.
  4. 运行 & 注销。Task在Executor上运行,执行完反馈给TaskScheduler与DAGScheduler,然后释放资源。

从整体流程看,Driver端创建SparkContext、提交作业、协调任务;Executor端执行Task。从内存使用角度看,Executor端内存设计比较复杂,下面予以概述。

二、Executor端内存设计

2.1 堆划分

3

Worker节点启动的Executor是一个JVM进程,因此Executor内存管理是建立在JVM内存管理上(On-Heap堆内内存),同时Spark也引入了Off-Heap(堆外内存),使之可以直接在系统内存中开辟空间,避免了在数据处理过程中不必要的序列化和反序列化开销,同时降低了GC开销。

2.1.1、On-Heap(堆内)

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

Spark对堆内内存的管理只是逻辑上“规划式”的管理,对象实例占用内存的申请和释放都是由JVM完成,而Spark只是在申请后和释放前记录这些内存,下面看看具体流程:

【1】 申请内存
1、Spark在代码中new一个对象实例;
2、JVM从堆内内存中分配空间,创建对象并返回对象引用;
3、Spark会保存该对象引用,记录对象占用的内存。

【2】释放内存
1、Spark记录该对象释放的内存,删除该对象的引用
2、等待JVM垃圾回收机制来释放掉对象占用的堆内内存。

Spark序列化小知识:
JVM对象可以以序列化方式存储,序列化的过程是将对象转换为二进制字节流,本质上可以理解为将非连续空间的链式存储转化为连续空间或块存储,在访问时需要进行序列化的逆过程—反序列化,将字节流转化为对象,序列化的方式可以节省存储空间,但增加了存储和读取时的计算开销。
Spark中序列化的对象会以字节流形式存在,占用内存大小可以直接计算,而对于非序列化的对象,占用的内存只能通过周期性地采样近似估算得到,即并不是每次新增数据项都会计算一次占用内存大小,这种方法降低时间开销,但可能误差较大,导致某一时刻实际内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值