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》

相關文章
相關標籤/搜索