spark的内存模型_分布式存储的应用场景

spark的内存模型_分布式存储的应用场景Spark内存管理模型详解

大家好,又见面了,我是你们的朋友全栈君。

本文首发于 www.yidooo.net/2018/07/29/… 转载请注明出处

引言

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

一个Spark Application一般包括Driver和Executor两种JVM进程。Driver为主控进程,负责创建Context,提交Job,并将Job转换为Task,协调Executor间的Task执行。而Executor主要负责执行具体的计算任务,将结果返回Driver。 由于Driver的内存管理比较简单,和一般的JVM程序区别不大,所以本文重点分析Executor的内存管理。所以,本文提到的内存管理都是指Executor的内存管理。

堆内内存和堆外内存

Executor作为一个JVM进程,它的内存管理是基于JVM之上的。所以JVM的内存管理包括两种方式:

  • 堆内内存管理(On-Heap):对象分配的在JVM的堆上,对象会受GC束缚。
  • 堆外内存管理(Off-Heap):对象通过序列化分配在JVM之外的内存里,由应用程序对其进行管理,且不受GC束缚。这种内存管理方式可以避免频繁的 GC,但缺点是必须自己编写内存申请和释放的逻辑。

一般来说对象读写速度是:on-heap > off-heap > disk

内存空间分配

在Spark中,支持两种内存管理方式:静态内存管理(Static Memory Manager)和统一内存管理(Unified Memory Manager)。

Spark为Storage内存和Execution内存的管理提供了统一的接口MemoryManager,同一个 Executor内的任务都调用这个接口的方法来申请或释放内存。MemoryManager的实现上,Spark 1.6以前默认采用的是静态内存管理([StaticMemoryManager]((github.com/apache/spar…))的方式;而在Spark1.6以后,默认采用的是统一内存管理(UnifiedMemoryManager)的方式。在中Spark 1.6+中,可以通过spark.memory.useLegacyMode参数启用静态内存管理。

静态内存管理(Static Memory Manager)

静态内存管理机制下,Storage内存、Execution内存和其他内存的大小在 Spark 应用程序运行期间均为固定的,但用户可以应用程序启动前进行配置。由于这种分配已经逐渐被淘汰,但出于兼容性考虑,Spark依然保留下来。有兴趣的话,可以参考:blog.csdn.net/Lin_wj1995/…

这边主要讲下静态内存管理的弊端:静态内存管理机制实现起来较为简单,但如果用户不熟悉Spark的存储机制,或没有根据具体的数据规模和计算任务或做相应的配置,很容易造成Storage内存和Execution内存中的一方剩余大量的空间,而另一方却早早被占满,不得不淘汰或移出旧的内容以存储新的内容。

统一内存管理(Unified Memory Manager)

Spark 1.6之后引入了统一内存管理机制,该机制与静态内存管理的区别在于,Storage内存和Execution内存是共享一块内存空间的,双方可以互相占用对方的空闲区域。

堆内模型

默认情况下,Spark仅使用了堆内内存。堆内内存的大小由Spark Application启动时的–executor-memory或spark.executor.memory 参数配置。Executor内运行的并发任务共享JVM堆内内存。

Executor端的堆内内存区域大致可以分为以下四大块:

  • Storage内存(Storage Memory):主要用于存储Spark的cache数据,例如RDD的缓存、Broadcast变量,Unroll数据等。
  • Execution内存(Execution Memory):主要用于存放 Shuffle、Join、Sort、Aggregation等计算过程中的临时数据。
  • 用户内存(User Memory):主要用于存储 RDD 转换操作所需要的数据,例如 RDD 依赖等信息。
  • 预留内存(Reserved Memory):系统预留内存,会用来存储Spark内部对象。

内存分布如下图所示:

堆外模型

Spark 1.6 开始引入了Off-heap memory(SPARK-11389)。默认情况下,堆外内存是关闭的,我们可以通过spark.memory.offHeap.enabled参数启用,通过spark.memory.offHeap.size设置堆外内存大小。相比堆内内存,堆外内存的模型比较简单,只包括Storage内存和Execution内存,其分布如下图所示:

如果堆外内存被启用,那么Executor内将同时存在堆内和堆外内存,两者的使用互补影响,这个时候Executor中的Execution内存是堆内的Execution 内存和堆外的Execution内存之和,同理,Storage内存也一样。下图为Spark堆内和堆外示意图

动态占用机制

  • 在程序提交时,会根据spark.memory.storageFraction参数设置Storage内存区域和Execution内存区域。
  • 在程序运行时,如果双方的空间不不足(存储空间不足以放下一个完整的Block),则按照LRU规则存储到磁盘;如果己方空间不足而对方空间有空余,则借用对方的空间。
  • Storage占用对方内存,可将占用的部分转存到硬盘,然后”归还”借用的空间。
  • Execution占用对方内存,目前的实现是无法让对方”归还”的。因为Shuffle过程产生的文件在后面一定会被使用到,而Cache在内存的数据不一定在后面使用,归还内存可能会导致性能严重下降。

参考资料

转载于:https://juejin.im/post/5b94937e6fb9a05cd456c337

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107325.html原文链接:https://javaforall.net

(0)
上一篇 2022年4月20日 下午3:40
下一篇 2022年4月20日 下午3:40


相关推荐

  • LeapFTP注册算法分析

    LeapFTP注册算法分析nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 很久没玩 OD 正好机器上试用版的 LeapFTP 过期了 于是心血来潮准备写个注册机 LeapFTP 版本 v2 76 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 记得以前跟过 LeapFTP 注册码分为两段 是明文存放在内存中 但是没有去细看算法 今天决定把算法搞定以后升级也方便 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 用 OD 载入 下注册表断点 为什么下注册表断点 因为我跟过 关键部分 0x00484d89 处停下

    2026年3月17日
    2
  • 面向对象进阶

    面向对象相关内置函数isinstance判断一个对象是否是一个类中的对象issubclass判断一个类是否是类中的子类返回布尔值反射反射的概念所谓的反射其实就是用字符串类型的名字去操作

    2022年3月29日
    43
  • 一文读懂扣子 Coze 知识库,从客服、话术到语料库全能指南,大模型入门到精通,收藏这篇就足够了!

    一文读懂扣子 Coze 知识库,从客服、话术到语料库全能指南,大模型入门到精通,收藏这篇就足够了!

    2026年3月12日
    2
  • Ubuntu18.04安装GCC8.3.0

    Ubuntu18.04安装GCC8.3.0转自:https://blog.csdn.net/bjzhaoxiao/article/details/102525241Ubuntu系统是自带GCC安装指令的aptinstallgcc,当前apt源中gcc版本为5.4.0,版本太低,推荐手动安装gcc8.3.0手动安装gcc8.3.0之前需要先确保安装gcc环境依赖GMP4.2+、MPFR2.3.1+、MPC0.8.0+,否则会报出以下错误configure:error:BuildingGCCrequiresGMP4.

    2022年7月24日
    5
  • html背景图片拉伸解决办法

    html背景图片拉伸解决办法html背景图片拉伸解决办法body{background-size:100%100%;//关键代码,直接拉伸背景图background-image:url(“img/99.jpg”);//背景图导入background-repeat:no-repeat;//不重复拉伸background-attachment:fixed;//此代码用于页面内容超出屏幕,

    2026年4月16日
    3
  • C语言中的选择排序

    C语言中的选择排序文章目录前言一、选择排序1.计算素组元素个数2.选择排序基本逻辑(例子是从大到小排列)3.具体实现1.外层循环:决定大回合个数每个大回合决出一个席位2.内层循环:决定小回合个数每个小回合进行1V1大战实力强的为擂主直至最后一位挑战者3.两个元素值的交换总结前言在C语言中用来解决排序问题的常见方法有选择排序和冒泡排序两种一、选择排序先上代码:1.计算素组元素个数通过sizeof()计算数组全体元素占空间的大小再去除以一个元素占空间的大小即可得到元素个数。2.选择排序基本

    2022年6月25日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号