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


存儲級別簡介

Spark中RDD提供了多種存儲級別,除去使用內存,磁盤等,還有一種是OFF_HEAP,稱之為 使用JVM堆外內存

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

使用OFF_HEAP的優點:在內存有限時,可以減少頻繁GC及不必要的內存消耗(減少內存的使用),提升程序性能。

Spark內存管理根據版本划分為兩個階段:spark1.6[官網給出spark1.5之前(包含spark1.5)]之前階段、spark1.6之后階段。

1.6.0及以后版本,使用的統一內存管理器,由UnifiedMemoryManager實現。

  • ü  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上運行相同的代碼會導致不同的行為。

為了兼容,您可以使用spark.memory.useLegacyMode參數(目前spark2.4版本中也依然保留這個靜態內存管理模型)啟用“舊”內存模型:

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》

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM