加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长百科 > 正文

Apache Spark 同一内存打点模子详解

发布时间:2019-02-06 05:51:42 所属栏目:站长百科 来源:过往记忆
导读:转载自过往影象(https://www.iteblog.com/) 本文链接: 【Apache Spark 同一内存打点模子详解】(https://www.iteblog.com/archives/2342.html) 本文将对 Spark 的内存打点模子举办说明,下面的说明所有是基于 Apache Spark 2.2.1 举办的。为了让下面的

转载自过往影象(https://www.iteblog.com/)

本文链接: 【Apache Spark 同一内存打点模子详解】( https://www.iteblog.com/archives/2342.html )

本文将对 Spark 的内存打点模子举办说明,下面的说明所有是基于 Apache Spark 2.2.1 举办的。为了让下面的文章看起来不死板,我不规划贴出代码层面的对象。文章仅对同一内存打点模块(UnifiedMemoryManager)举办说明,如对之前的静态内存打点感乐趣,请参阅网上其他文章。

我们都知道 Spark 可以或许有用的操作内存并举办漫衍式计较,其内存打点模块在整个体系中饰演着很是重要的脚色。为了更好地操作 Spark,深入地领略其内存打点模子具有很是重要的意义,这有助于我们对 Spark 举办更好的调优;在呈现各类内存题目时,可以或许摸清脑子,找到哪块内存地区呈现题目。下文先容的内存模子所有指 Executor 端的内存模子, Driver 端的内存模子本文不做先容。同一内存打点模块包罗了堆内内存(On-heap Memory)和堆外内存(Off-heap Memory)两大地区,下面临这两块地区举办具体的声名

文章目次

1 堆内内存(On-heap Memory)

2 堆外内存(Off-heap Memory)

3 Execution 内存和 Storage 内存动态调解

4 Task 之间内存漫衍

5 一个示例

5.1 只用了堆内内存

5.2 用了堆内和堆外内存

堆内内存(On-heap Memory)

默认环境下,Spark 仅仅行使了堆内内存。Executor 端的堆内内存地区大抵可以分为以下四大块:

·Execution 内存 :首要用于存放 Shuffle、Join、Sort、Aggregation 等计较进程中的姑且数据

·Storage 内存 :首要用于存储 spark 的 cache 数据,譬喻RDD的缓存、unroll数据;

·用户内存(User Memory) :首要用于存储 RDD 转换操纵所必要的数据,譬喻 RDD 依靠等信息。

·预留内存(Reserved Memory) :体系预留内存,会用来存储Spark内部工具。

整个 Executor 端堆内内存假如用图来暗示的话,可以归纳综合如下:

Apache Spark 同一内存打点模子详解

假如想实时相识Spark、Hadoop可能Hbase相干的文章,接待存眷微信民众帐号:iteblog_hadoop

我们对上图举办以下声名:

· systemMemory = Runtime.getRuntime.maxMemory,着实就是通过参数 spark.executor.memory 或 --executor-memory 设置的。

· reservedMemory 在 Spark 2.2.1 中是写死的,其值便是 300MB,这个值是不能修改的(假如在测试情形下,我们可以通过 spark.testing.reservedMemory 参数举办修改);

· usableMemory = systemMemory - reservedMemory,这个就是 Spark 可用内存;

堆外内存(Off-heap Memory)

Spark 1.6 开始引入了Off-heap memory(详见SPARK-11389)。这种模式不在 JVM 内申请内存,而是挪用 Java 的 unsafe 相干 API 举办诸如 C 说话内里的 malloc() 直接向操纵体系申请内存,因为这种方法不进过 JVM 内存打点,以是可以停止频仍的 GC,这种内存申请的弱点是必需本身编写内存申请和开释的逻辑。

默认环境下,堆外内存是封锁的,我们可以通过 spark.memory.offHeap.enabled 参数启用,而且通过 spark.memory.offHeap.size 配置堆外内存巨细,单元为字节。假如堆外内存被启用,那么 Executor 内将同时存在堆内和堆外内存,两者的行使互补影响,这个时辰 Executor 中的 Execution 内存是堆内的 Execution 内存和堆外的 Execution 内存之和,同理,Storage 内存也一样。对比堆内内存,堆外内存只区分 Execution 内存和 Storage 内存,其内存漫衍如下图所示:

Apache Spark 同一内存打点模子详解

假如想实时相识Spark、Hadoop可能Hbase相干的文章,接待存眷微信民众帐号:iteblog_hadoop

上图中的 maxOffHeapMemory 便是 spark.memory.offHeap.size 参数设置的。

Execution 内存和 Storage 内存动态调解

仔细的同窗必定看到上面两张图中的 Execution 内存和 Storage 内存之间存在一条虚线,这是为什么呢?

用过 Spark 的同窗应该知道,在 Spark 1.5 之前,Execution 内存和 Storage 内存分派是静态的,换句话说就是假如 Execution 内存不敷,纵然 Storage 内存有很大空闲措施也是无法操作到的;反之亦然。这就导致我们很难举办内存的调优事变,我们必需很是清晰地相识 Execution 和 Storage 两块地区的内存漫衍。而今朝 Execution 内存和 Storage 内存可以相互共享的。也就是说,假如 Execution 内存不敷,而 Storage 内存有空闲,那么 Execution 可以从 Storage 中申请空间;反之亦然。以是上图中的虚线代表 Execution 内存和 Storage 内存是可以跟着运作动态调解的,这样可以有用地操作内存资源。Execution 内存和 Storage 内存之间的动态调解可以归纳综合如下:Apache Spark 同一内存打点模子详解

假如想实时相识Spark、Hadoop可能Hbase相干的文章,接待存眷微信民众帐号:iteblog_hadoop

详细的实现逻辑如下:

· 措施提交的时辰我们城市设定根基的 Execution 内存和 Storage 内存地区(通过 spark.memory.storageFraction 参数配置);

· 在措施运行时,假如两边的空间都不敷时,则存储到硬盘;将内存中的块存储到磁盘的计策是凭证 LRU 法则举办的。若己方空间不敷而对方空余时,可借用对方的空间;(存储空间不敷是指不敷以放下一个完备的 Block)

· Execution 内存的空间被对方占用后,可让对方将占用的部门转存到硬盘,然后"偿还"借用的空间

· Storage 内存的空间被对方占用后,今朝的实现是无法让对方"偿还",由于必要思量 Shuffle 进程中的许多身分,实现起来较为伟大;并且 Shuffle 进程发生的文件在后头必然会被行使到,而 Cache 在内存的数据不必然在后头行使。

留意,上面说的借用对方的内存必要借用方和被借用方的内存范例都一样,都是堆内内存可能都是堆外内存,不存在堆内内存不足去借用堆外内存的空间。

Task 之间内存漫衍

为了更好地行使行使内存,Executor 内运行的 Task 之间共享着 Execution 内存。详细的,Spark 内部维护了一个 HashMap 用于记录每个 Task 占用的内存。当 Task 必要在 Execution 内存地区申请 numBytes 内存,其先判定 HashMap 内里是否维护着这个 Task 的内存行使环境,假如没有,则将这个 Task 内存行使置为0,而且以 TaskId 为 key,内存行使为 value 插手到 HashMap 内里。之后为这个 Task 申请 numBytes 内存,假如 Execution 内存地区正好有大于 numBytes 的空闲内存,则在 HashMap 内里将当前 Task 行使的内存加上 numBytes,然后返回;假如当前 Execution 内存地区无法申请到每个 Task 最小可申请的内存,则当前 Task 被阻塞,直到有其他使命开释了足够的执行内存,该使命才可以被叫醒。每个 Task 可以行使 Execution 内存巨细范畴为 1/2N ~ 1/N,个中 N 为当前 Executor 内正在运行的 Task 个数。一个 Task 可以或许运行必需申请到最小内存为 (1/2N * Execution 内存);当 N = 1 的时辰,Task 可以行使所有的 Execution 内存。

好比假如 Execution 内存巨细为 10GB,当前 Executor 内正在运行的 Task 个数为5,则该 Task 可以申请的内存范畴为 10 / (2 * 5) ~ 10 / 5,也就是 1GB ~ 2GB的范畴。

一个示例

为了更好的领略上面堆内内存和堆外内存的行使环境,这里给出一个简朴的例子。

只用了堆内内存

此刻我们提交的 Spark 功课关于内存的设置如下:

1

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!