Spark中的内存管理(一)

简介: Spark应用经常遇到的问题很多都是内存问题,本文对Driver和Executor的内存管理机制进行了相关介绍。

一个Spark应用运行的过程如下所示:
_2018_12_23_8_17_04

  • Driver
    用户的主程序提交到Driver中执行,在Driver中创建SparkContext,SparkContext初始化DAGScheduler和TaskScheduler,作为coordinator负责从AppMaster申请资源,并将作业的Task调度到Executor上面执行。

在yarn-cluster模式下,AppMaster中包含了Driver,在YARN中启动,spark-submit客户端kill掉不影响程序的运行;
在yarn-client模式下,Driver在spark-submit的客户端启动(不在YARN中),跟AppMaster是分离的,spark-submit客户端kill掉会导致Spark程序挂掉(如spark-sql/spark-shell等都是以yarn-client的方式提交)

Executor上面运行的每个MapTask结束后都会有MapStatus汇报给Driver, 当MapTask数量非常多的时候可能会导致Driver出现OOM,此时需要调整Driver的内存大小,通过--conf spark.driver.memory=4G或者--driver-memory 4G来进行设置。

  • Executor
    实际执行Task的节点,Executor的个数由--conf spark.executor.instances=4或者--num-executors 4来设置;每个Executor里面并发跑的Task个数由--conf spark.executor.cores=2或者--executor-cores指定。

Executor的内存由--conf spark.executor.memory=4G或者--executor-memory 4G设置。

Spark内存管理

上面介绍了Spark中两个角色(Driver/Executor),其中Executor是实际运行Task的节点,Spark内存管理主要在Executor上面。

Executor内存使用结构

_2018_12_23_9_54_06

如上图所示, Spark on YARN模式下一个Executor的内存使用情况:

整个Executor是YARN的一个container,所以它的总内存受yarn.scheduler.maximum-allocation-mb的参数控制;

当用户提交作业的时候通过spark.executor.memory参数设置了executor的堆内存(heapsize),这部分内存的使用情况如上图所示:

  • 系统预留(固定300MB)
    详见SPARK-12081
  • spark.memory.fraction
    该参数控制executor内用户计算(execution)和存储(storage)总占用多少内存,即(M-R)*spark.memory.fraction 大小的内存; 剩余的(M-R)*(1-spark.memory.fraction)用于Spark内部的metadata以及用户数据结构等使用

对于spark.executor.memroyOverhead,它是executor可额外使用的堆外(off-heap)内存,比如spark的shuffle过程使用的netty就会使用到堆外内存,如果程序有遇到相关的oom错误,可以尝试调大该参数。该内存不属于上面spark.executor.memory(on-heap),但是它们的总和不能超过yarn.scheduler.maximum-allocation-mb.

execution/storage内存管理

上图中execution/storage的内存((M-R)*spark.memroy.fraction)是Task在executor中运行需要用到的内存,它们通过UnifiedMemoryManager这个统一内存管理器来管理。

UnifiedMemoryManager中的execution和storage的管理没有硬性的边界控制(比如execution固定占比多少),它们之间是一个软边界,初始的边界由spark.memory.storageFraction来设置(默认0.5),但这个并不是一个固定的边界:
a) 当execution不够的时候,可以从storage侧借内存,如storage基本没使用(如没有cache数据等),execution可以从storage借内存甚至全部都借完,即使后续有storage需要用内存也不能强制从execution拿回,除非execution后续自己释放了部分内存,storage才能拿来使用;

b) 当storage不够的时候,如果execution有空闲多余的内存,则也可以借,但是后续如果execution又需要更多内存了则可以强制从storage拿回内存(如可以将storge的数据写到磁盘,然后释放对应的内存),直到storage使用的内存减少到spark.memory.storageFraction的比例。

Task内存管理

一个Executor可以同时并发执行多个Task(通过spark.executor.cores控制),而每个Task在运行的过程中都需要从Executor申请内存来使用,那Executor如何将内存分配给并发运行的多个Task呢? 这块留到下一篇文章来介绍。

_

相关实践学习
数据湖构建DLF快速入门
本教程通过使⽤数据湖构建DLF产品对于淘宝用户行为样例数据的分析,介绍数据湖构建DLF产品的数据发现和数据探索功能。
快速掌握阿里云 E-MapReduce
E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、HBase,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。 本课程主要介绍阿里云 E-MapReduce 的使用方法。
目录
相关文章
|
26天前
|
SQL 分布式计算 Hadoop
Spark分布式内存计算框架
Spark分布式内存计算框架
49 0
|
1月前
|
机器学习/深度学习 分布式计算 数据处理
Spark是一个基于内存的通用数据处理引擎,可以进行大规模数据处理和分析
【5月更文挑战第2天】Spark是一个基于内存的通用数据处理引擎,可以进行大规模数据处理和分析
36 3
|
10月前
|
分布式计算 监控 Java
Spark学习---7、Spark内核(源码提交流程、任务执行、Shuffle、内存管理)(一)
Spark学习---7、Spark内核(源码提交流程、任务执行、Shuffle、内存管理)(一)
|
分布式计算 Scala Spark
【Spark】【RDD】从内存(集合)创建RDD
【Spark】【RDD】从内存(集合)创建RDD
138 0
Spark 通用的性能配置方法:内存和CPU的配置
前言 本文主要介绍关于通过配置Spark任务运行时的内存和CPU(Vcore)来提升Spark性能的方法。通过配置内存和CPU(Vcore)是比较基础、通用的方法。本文出现的Demo以X-Pack Spark数据工作台为背景介绍,数据工作台的详细介绍请参考:数据工作台。
5505 0
|
存储 机器学习/深度学习 分布式计算
10月29日社区直播【Spark Shuffle RPMem扩展: 借助持久内存与RDMA加速Spark 数据分析】
介绍如何利用持久化内存与高性能RDMA 网络来加速Spark Shuffle。
10月29日社区直播【Spark Shuffle RPMem扩展: 借助持久内存与RDMA加速Spark 数据分析】
|
SQL 存储 缓存
Spark在处理数据的时候,会将数据都加载到内存再做处理吗?
对于Spark的初学者,往往会有一个疑问:Spark(如SparkRDD、SparkSQL)在处理数据的时候,会将数据都加载到内存再做处理吗?
Spark在处理数据的时候,会将数据都加载到内存再做处理吗?
|
存储 SQL 分布式计算
9月10日 Spark 社区直播【利用持久内存提速Spark】
主要探讨如何在Spark上使用持久内存这一新技术来进一步提速性能。具体会介绍基于Plasma的共享内存方案来提速SQL数据源访问的性能以及利用持久内存扩展Spark现有内存磁盘存储层级来提速RDD cache在迭代式计算中的效果。
9月10日 Spark 社区直播【利用持久内存提速Spark】
|
1天前
|
存储 小程序 编译器
【C语言基础】:数据在内存中的存储
【C语言基础】:数据在内存中的存储
|
2天前
|
存储 C++
C primer plus 学习笔记 第12章 存储类别、链接和内存管理
C primer plus 学习笔记 第12章 存储类别、链接和内存管理