前言

下面的分析基于对spark2.1.0版本的分析,对于1.x的版本可以有区别。

内存配置

key

默认

解释

spark.memory.fraction

0.6

spark可以直接使用的内存大小系数

spark.memory.storageFraction

0.5

spark存储可以直接使用的内存大小系数

spark.memory.offHeap.enabled

false

是否开启spark使用jvm内存之外的内存

spark.memory.offHeap.size

0

jvm之外,spark可以用多少内存

内存划分策略

如图1,spark在内存上划分出4部分空间,分别为预留空间(默认300M),Spark执行空间(Execution),Spark存储空间(Storage)和用户使用空间。

下面用一个实际案例描述一下这4部分空间:

假设给executor分配1G,也就是1024MB,Spark会留出300MB,这300MB不能作为缓存或者rdd相关操作使用,可以理解成防止OOM的一种策略。当`spark.memory.fraction`为0.6时(默认),(1024 - 300) * 0.6 = 434MB,这434MB就是Spark用于rdd缓存或者rdd执行的内存大小,也就是Spark可以随意使用的max memory。剩下的资源是给用户留下的内存大小。而`spark.memory.storageFraction`则是声明了可以用于存储的大小,默认是0.5,也就是说Spark任务中,存储Storage和执行Execution各占50%内存空间也就是434*0.5=217MB。

图1

在实际内存申请过程中,Spark为Storage和Execution各自维护了一个内存资源池,用于控制和协调内存资源的使用,在钨丝计划的路线下,Spark支持onHeap和offHeap两种内存分配机制,但是分配流程是一致的。参考图2,在Execution的内存池资源充足的情况下,直接获取需要的Execution资源,而在不足情况下,允许Execution借用Storage的内存资源,首先判断Storage资源池剩余的资源是否满足要去,如果剩余也不足,那么尝试将已经存在的block(block是rdd缓存或者shuflle的存储单元)剔除,直到获取到充足的内存,如果资源依然不够Execution,那么该Execution会阻塞,知道获取到全部资源。 而反过来需要获取Storage的内存资源,也是先检查Execution内存池是否有剩余,如果依旧不足,呢就去尝试将已经存在的block剔除,直到获取到充足的内存(和Execution调用的是一个函数evictBlocksToFreeSpace),最后获取不到足够的资源就直接返回失败。这相比Execution是有区别的,Storage不够可以spill,而Execution资源不够就必须阻塞等待。

图2

内存划分粒度

Spark对于内存的控制的最小粒度是Task,一个executor也就是一个JVM维护一个Execution内存池和Storage内存池,也就是说一个executor能同时执行多少个task除了收到cpu的影响,还受到竞争内存资源的影响,其实上面已经讲了很多了,下面再详细分析一下task如何竞争内存资源。

task获取Execution内存

task获取Execution的内存也是相对公平的控制,将内存控制在task平均使用内存和task平均使用内存一半之间。相关代码如下:

val maxMemoryPerTask = maxPoolSize / numActiveTasks
val minMemoryPerTask = poolSize / (2 * numActiveTasks)
// How much we can grant this task; keep its share within 0 <= X <= 1 /
numActiveTasks
val maxToGrant = math.min(numBytes, math.max(0, maxMemoryPerTask - curMem))
// Only give it as much memory as is free, which might be none if it reached 1
/ numTasks
val toGrant = math.min(maxToGrant, memoryFree)

当获取不到内存时,Spark会让请求的task等待,直到有其他task释放资源,然后该task再去抢占资源。

task获取Storage内存

storage内存的获取就相对复杂一点,因为这受到rdd的cache,persist相关操作的影响。因此和BlockManager和MemStore有关

如果申请的内存大于storage内存池剩余的内存,那么获取Execution内存池是否有剩余,如果有的话就释放Math.min(executionPool.memoryFree,
numBytes)。在申请内存之前,还做了一件事件,就是去blockManager尝试释放内存,如果缓存的所有内存实例中,某个blockId下的rdd的id是空,并且存储模式相同(都用jvm或者都不用jvm),那么就会将该blockId释放。如果空余资源小于申请的资源,那么就会申请失败。

代码相关类

MemoryManager

UnifiedMemoryManager

MemoryPool

StorageMemoryPool

ExecutionMemoryPool

MemoryStore

spark内存管理分析的更多相关文章

  1. spark 源码分析之十五 -- Spark内存管理剖析

    本篇文章主要剖析Spark的内存管理体系. 在上篇文章 spark 源码分析之十四 -- broadcast 是如何实现的?中对存储相关的内容没有做过多的剖析,下面计划先剖析Spark的内存机制,进而 ...

  2. Spark内存管理机制

    Spark内存管理机制 Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行 ...

  3. Apache Spark 内存管理详解(转载)

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  4. spark内存管理器--MemoryManager源码解析

    MemoryManager内存管理器 内存管理器可以说是spark内核中最重要的基础模块之一,shuffle时的排序,rdd缓存,展开内存,广播变量,Task运行结果的存储等等,凡是需要使用内存的地方 ...

  5. spark内存管理详解

    Spark 作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色.理解 Spark 内存管理的基本原理,有助于更好地开发 Spark 应用程序和进行性能调优.本文旨在梳理出 ...

  6. 【Spark-core学习之八】 SparkShuffle & Spark内存管理

    [Spark-core学习之八] SparkShuffle & Spark内存管理环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 ...

  7. Spark内存管理之钨丝计划

    Spark内存管理之钨丝计划 1. 钨丝计划的产生的原因 2. 钨丝计划内幕详解  一:“钨丝计划”产生的本质原因 1, Spark作为一个一体化多元化的(大)数据处理通用平台,性能一直是其根本性的追 ...

  8. Spark(四十六):Spark 内存管理之—OFF_HEAP

    存储级别简介 Spark中RDD提供了多种存储级别,除去使用内存,磁盘等,还有一种是OFF_HEAP,称之为 使用JVM堆外内存 https://github.com/apache/spark/blo ...

  9. Spark 内存管理

    Spark 内存管理 Spark 执行应用程序时, 会启动 Driver 和 Executor 两种 JVM 进程 Driver 负责创建 SparkContext 上下文, 提交任务, task的分 ...

随机推荐

  1. ELK基础学习

    第壹部分:Elasticsearch 一 .Elasticsearch增删改查1.数据写入:HTTP method:POSTURL:http://127.0.0.1:9200/index-docs-n ...

  2. 关于Memcached反射型DRDoS攻击分析

    一.Memcached反射攻击原理 1.反射DRDoS攻击: DRDoS攻击时DoS攻击的一种,DoS是指通过发送或引发大量的资源消耗导致服务不可用的一种攻击方式,中文称之为拒绝服务攻击.DRDoS是 ...

  3. 【BZOJ1720】[Usaco2006 Jan]Corral the Cows 奶牛围栏 双指针法

    [BZOJ1720][Usaco2006 Jan]Corral the Cows 奶牛围栏 Description Farmer John wishes to build a corral for h ...

  4. Spring MVC 框架学习

    一.spirng的简介 Spring是一个开源框架,它由Rod Johnson创建.它是为了解决企业应用开发的复杂性而创建的.Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情. ...

  5. 使用MySQLMTOP监控MySQL性能(二)

    一.服务器角色 服务器角色 172.18.35.29 10.160.22.14 (MySQL Master) 10.160.22.47 (MySQL Slave) 监控点 YES NO NO 被监控点 ...

  6. Oracle命令(三):Oracle用户

    1.显示当前用户名 select user from dual; show user 2.显示当然用户有哪些表 select * from tab; 3.显示当所有用户的表 select * from ...

  7. javascript 之获取 百度地址参数方法

    原生态的JavaScript对DOM的操作 比jquery更方便,特别是当没有id  或class 可以获取的时候,只有用tag名获取 HTML DOM Element 对象操作  http://ww ...

  8. js判断移动端和PC端跳转不同页面

    方法一: /* * * 判断PC端与WAP端 */ var mobile_bs = { versions: function() { var u = navigator.userAgent; retu ...

  9. 【转】SQL Server编程游标

    在关系数据库中,我们对于查询的思考是面向集合的.而游标打破了这一规则,游标使得我们思考方式变为逐行进行.对于类C的开发人员来着,这样的思考方式会更加舒服. 正常面向集合的思维方式是: 而对于游标来说: ...

  10. python基础之函数式编程、匿名函数、内置函数

    一 函数式编程 不修改外部状态. 模仿数学里得函数进行编程. 用函数编程写出得代码相当精简. 可读性比较差. 例子: y=2*x+1 x=1 def test(x): return 2*x+1 tes ...