Spark内存管理(2)—— 统一内存管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lemonZhaoTao/article/details/82027469

Spark内存管理系列文章:
Spark内存管理(1)—— 静态内存管理

堆内内存

Spark 1.6之后引入的统一内存管理机制,与静态内存管理的区别在于Storage和Execution共享同一块内存空间,可以动态占用对方的空闲区域
这里写图片描述

其中最重要的优化在于动态占用机制,其规则如下:

  • 设定基本的Storage内存和Execution内存区域(spark.storage.storageFraction参数),该设定确定了双方各自拥有的空间的范围

  • 双方的空间都不足时,则存储到硬盘
    若己方空间不足而对方空余时,可借用对方的空间(存储空间不足是指不足以放下一个完整的 Block)

  • Execution的空间被对方占用后,可让对方将占用的部分转存到硬盘,然后”归还”借用的空间

  • Storage的空间被对方占用后,无法让对方”归还”,因为需要考虑 Shuffle过程中的很多因素,实现起来较为复杂

动态内存占用机制

动态占用机制如下图所示:
这里写图片描述

凭借统一内存管理机制,Spark 在一定程度上提高了堆内和堆外内存资源的利用率,降低了开发者维护 Spark 内存的难度,但并不意味着开发者可以高枕无忧
譬如:如果Storage的空间太大或者说缓存的数据过多,反而会导致频繁的全量垃圾回收,降低任务执行时的性能,因为缓存的 RDD 数据通常都是长期驻留内存的。所以要想充分发挥 Spark 的性能,需要开发者进一步了解存储内存和执行内存各自的管理方式和实现原理

堆外内存

如下图所示,相较于静态内存管理,引入了动态占用机制
这里写图片描述

计算公式

spark从1.6版本以后,默认的内存管理方式就调整为统一内存管理模式
由UnifiedMemoryManager实现

Unified MemoryManagement模型,重点是打破运行内存和存储内存之间的界限,使spark在运行时,不同用途的内存之间可以实现互相的拆借

Reserved Memory

这部分内存是预留给系统使用,在1.6.1默认为300MB,这一部分内存不计算在Execution和Storage中;可通过spark.testing.reservedMemory进行设置;然后把实际可用内存减去这个reservedMemor得到usableMemory
ExecutionMemory 和 StorageMemory 会共享usableMemory * spark.memory.fraction(默认0.75)
注意:

  • 在Spark 1.6.1 中spark.memory.fraction默认为0.75

  • 在Spark 2.2.0 中spark.memory.fraction默认为0.6

User Memory

分配Spark Memory剩余的内存,用户可以根据需要使用
在Spark 1.6.1中,默认占(Java Heap - Reserved Memory) * 0.25
在Spark 2.2.0中,默认占(Java Heap - Reserved Memory) * 0.4

Spark Memory

计算方式为:(Java Heap – ReservedMemory) * spark.memory.fraction
在Spark 1.6.1中,默认为(Java Heap - 300M) * 0.75
在Spark 2.2.0中,默认为(Java Heap - 300M) * 0.6
Spark Memory又分为Storage Memory和Execution Memory两部分
两个边界由spark.memory.storageFraction设定,默认为0.5

下一篇文章中,将带来对Spark统一内存管理设计理念的介绍

猜你喜欢

转载自blog.csdn.net/lemonZhaoTao/article/details/82027469
今日推荐