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

存储级别简介

Spark中RDD提供了多种存储级别,除去使用内存,磁盘等,还有一种是OFF_HEAP,称之为 使用JVM堆外内存html

https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/storage/StorageLevel.scalajava

使用OFF_HEAP的优势:在内存有限时,能够减小频繁GC及没必要要的内存消耗(减小内存的使用),提高程序性能。git

Spark内存管理根据版本划分为两个阶段:spark1.6[官网给出spark1.5以前(包含spark1.5)]以前阶段、spark1.6以后阶段。github

1.6.0及之后版本,使用的统一内存管理器,由UnifiedMemoryManager实现。apache

  • ü  MemoryManger在spark1.6以前采用静态内存管理

(StaticMemoryManager[https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/memory/StaticMemoryManager.scala]),编程

  • ü  Spark1.6以后默认为统一内存管理

(UnifiedMemoryManager[https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/memory/UnifiedMemoryManager.scala])统一内存管理模块包括了堆内内存(On-heap Memory)和堆外内存(Off-heap Memory)两大区域并发

从1.6.0版本开始,Spark内存管理模型发生了变化。旧的内存管理模型由StaticMemoryManager类实现,如今称为“legacy(遗留)”。默认状况下,“Legacy”模式被禁用,这意味着在Spark 1.5.x和1.6.0上运行相同的代码会致使不一样的行为。app

为了兼容,您可使用spark.memory.useLegacyMode参数(目前spark2.4版本中也依然保留这个静态内存管理模型)启用“旧”内存模型:less

spark.memory.useLegacyMode=true(默认为false)

该参数官网给出的解释:性能

Whether to enable the legacy memory management mode used in Spark 1.5 and before. The legacy mode rigidly partitions the heap space into fixed-size regions, potentially leading to excessive spilling if the application was not tuned. The following deprecated memory fraction configurations are not read unless this is enabled:

spark.shuffle.memoryFraction

spark.storage.memoryFraction

spark.storage.unrollFraction

在Spark1.x之前,默认的off_heap使用的是Tachyon。可是Spark中默认操做Tachyon的TachyonBlockManager开发完成以后,代码就再也不更新。当Tachyon升级为Alluxio以后移除不使用的API,致使Spark默认off_heap不可用(spark1.6+)。

错误状况可参考:https://alluxio.atlassian.net/browse/ALLUXIO-1881

Spark2.0的OFF_HEAP

从spark2.0开始,移除默认的TachyonBlockManager以及ExternalBlockManager相关的API。

移除状况可参考:https://issues.apache.org/jira/browse/SPARK-12667。

可是在Spark2.x的版本中,OFF_HEAP这一存储级别,依然存在:

 

https://github.com/apache/spark/blob/branch-2.4/core/src/main/java/org/apache/spark/memory/MemoryMode.java

那么,这里的OFF_HEAD 数据是如何存储的呢?

在org.apache.spark.memory中,有一个MemoryMode,MemoryMode标记了是使用ON_HEAP仍是OFF_HEAP。

 

https://github.com/apache/spark/blob/branch-2.4/core/src/main/java/org/apache/spark/memory/MemoryMode.java

在org.apache.spark.storage.memory.MemoryStore中,根据MemoryMode类型来调用不一样的存储。

 

https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/storage/memory/MemoryStore.scala

在MemoryStore中putIteratorAsBytes方法,是用于存储数据的方法。

 

其实真正管理(存储)values的对象是valuesHolder,valueHolder是SerializedValuesHolder的类对象,咱们看下SerializedValuesHolder是怎么定义的。

 

在该方法中,OFF_HEAP使用的是org.apache.spark.unsafe.Platform(https://github.com/apache/spark/blob/master/common/unsafe/src/main/java/org/apache/spark/unsafe/Platform.java)来作底层存储的,Platform是利用java unsafe API实现的一个访问off_heap的类,因此,spark2.x的OFF_HEAP就是利用java unsafe API实现的内存管理。

Spark2.x OFF_HEAP优点:

  • ü  优势:在内存有限时,能够减小频繁GC及没必要要的内存消耗(减小内存的使用,),提高程序性能。
  • ü  缺点:没有数据备份,也不能像alluxio那样保证数据高可用,丢失数据则须要从新计算。

参考

《Spark2.x 内存管理之---OFF_HEAP https://blog.csdn.net/qq_21439395/article/details/80773121

  • 关于 java  unsafe API 可参考:

《Java中Unsafe类详解 https://www.cnblogs.com/mickole/articles/3757278.html 》

《JAVA并发编程学习笔记之Unsafe类  https://blog.csdn.net/aesop_wubo/article/details/7537278》

相关文章
相关标签/搜索