成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Apache Spark 統一內存管理模型詳解

存儲 存儲軟件 Spark
本文將對 Spark 的內存管理模型進行分析,下面的分析全部是基于 Apache Spark 2.2.1 進行的。為了讓下面的文章看起來不枯燥,我不打算貼出代碼層面的東西。文章僅對統一內存管理模塊(UnifiedMemoryManager)進行分析。

本文將對 Spark 的內存管理模型進行分析,下面的分析全部是基于 Apache Spark 2.2.1 進行的。為了讓下面的文章看起來不枯燥,我不打算貼出代碼層面的東西。文章僅對統一內存管理模塊(UnifiedMemoryManager)進行分析。

我們都知道 Spark 能夠有效的利用內存并進行分布式計算,其內存管理模塊在整個系統中扮演著非常重要的角色。為了更好地利用 Spark,深入地理解其內存管理模型具有非常重要的意義,這有助于我們對 Spark 進行更好的調優;在出現各種內存問題時,能夠摸清頭腦,找到哪塊內存區域出現問題。下文介紹的內存模型全部指 Executor 端的內存模型, Driver 端的內存模型本文不做介紹。統一內存管理模塊包括了堆內內存(On-heap Memory)和堆外內存(Off-heap Memory)兩大區域,下面對這兩塊區域進行詳細的說明。

堆內內存(On-heap Memory)

默認情況下,Spark 僅僅使用了堆內內存。Executor 端的堆內內存區域大致可以分為以下四大塊:

  • Execution 內存:主要用于存放 Shuffle、Join、Sort、Aggregation 等計算過程中的臨時數據
  • Storage 內存:主要用于存儲 spark 的 cache 數據,例如RDD的緩存、unroll數據;
  • 用戶內存(User Memory):主要用于存儲 RDD 轉換操作所需要的數據,例如 RDD 依賴等信息。
  • 預留內存(Reserved Memory):系統預留內存,會用來存儲Spark內部對象。

整個 Executor 端堆內內存如果用圖來表示的話,可以概括如下:

如果想及時了解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 內存,其內存分布如下圖所示:

如果想及時了解Spark、Hadoop或者Hbase相關的文章,歡迎關注微信公共帳號:iteblog_hadoop

Execution 內存和 Storage 內存動態調整

細心的同學肯定看到上面兩張圖中的 Execution 內存和 Storage 內存之間存在一條虛線,這是為什么呢?

用過 Spark 的同學應該知道,在 Spark 1.5 之前,Execution 內存和 Storage 內存分配是靜態的,換句話說就是如果 Execution 內存不足,即使 Storage 內存有很大空閑程序也是無法利用到的;反之亦然。這就導致我們很難進行內存的調優工作,我們必須非常清楚地了解 Execution 和 Storage 兩塊區域的內存分布。而目前 Execution 內存和 Storage 內存可以互相共享的。也就是說,如果 Execution 內存不足,而 Storage 內存有空閑,那么 Execution 可以從 Storage 中申請空間;反之亦然。所以上圖中的虛線代表 Execution 內存和 Storage 內存是可以隨著運作動態調整的,這樣可以有效地利用內存資源。Execution 內存和 Storage 內存之間的動態調整可以概括如下:

如果想及時了解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 個數。

比如如果 Execution 內存大小為 10GB,當前 Executor 內正在運行的 Task 個數為5,則該 Task 可以申請的內存范圍為 10 / (2 * 5) ~ 10 / 5,也就是 1GB ~ 2GB的范圍。

一個示例

為了更好的理解上面堆內內存和堆外內存的使用情況,這里給出一個簡單的例子。

只用了堆內內存

現在我們提交的 Spark 作業關于內存的配置如下:

--executor-memory 18g

由于沒有設置 spark.memory.fraction 和 spark.memory.storageFraction 參數,我們可以看到 Spark UI 關于 Storage Memory 的顯示如下:

如果想及時了解Spark、Hadoop或者Hbase相關的文章,歡迎關注微信公共帳號:iteblog_hadoop

上圖很清楚地看到 Storage Memory 的可用內存是 10.1GB,這個數是咋來的呢?根據前面的規則,我們可以得出以下的計算:

現在終于對上了。

具體將字節轉換成 GB 的計算邏輯如下(core 模塊下面的 /core/src/main/resources/org/apache/spark/ui/static/utils.js):

用了堆內和堆外內存

現在如果我們啟用了堆外內存,情況咋樣呢?我們的內存相關配置如下:

責任編輯:武曉燕 來源: Hadoop技術博文
相關推薦

2017-04-01 14:01:50

Apache Spar內存管理

2018-12-18 14:37:26

Spark內存管理

2019-05-30 11:04:52

內存Spark管理

2018-05-31 20:49:50

Spark堆內內存優化機制

2024-03-26 00:33:59

JVM內存對象

2009-06-24 16:50:11

Java內存模型

2025-06-06 06:25:07

2010-12-21 18:07:39

2011-06-03 10:19:59

iphone Objective-

2010-09-25 12:38:40

JVM內存模型

2014-02-14 15:43:16

ApacheSpark

2019-10-10 16:20:23

spark內存管理

2019-04-17 14:44:42

Spark內存源碼

2011-07-19 15:37:13

Oracle 10g內存管理PGA

2019-06-27 11:18:00

Spark內存大數據

2010-09-26 13:23:13

JVM內存管理機制

2011-11-30 12:32:38

企業防毒防毒方案拯救三

2011-07-01 10:16:08

C++內存管理

2010-12-10 15:40:58

JVM內存管理

2011-06-29 17:20:20

Qt 內存 QOBJECT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 69xxx免费| 99精品欧美一区二区三区综合在线 | 日韩成人免费视频 | 欧美在线不卡 | 成人免费视频一区二区 | 成人在线视频免费观看 | 欧美一区二区在线看 | caoporn免费| 亚洲欧美一区二区三区国产精品 | 欧美日韩国产传媒 | 99国产精品99久久久久久 | 91精品国产欧美一区二区成人 | 97精品超碰一区二区三区 | 一级视频在线免费观看 | 国产一区二区三区久久久久久久久 | 在线观看视频你懂得 | 国产精品毛片av | 成人欧美一区二区 | 在线观看亚洲专区 | 欧美6一10sex性hd | 日日操视频 | 男人视频网站 | 五月免费视频 | 亚洲国产二区 | 久久久精品一区 | 黄色操视频 | 日韩在线视频播放 | 国产在线精品一区二区 | www.国产.com| 欧美日韩在线视频一区 | 91在线一区二区三区 | 色妹子综合网 | 青青草一区二区 | 国产激情免费视频 | 精品婷婷 | 日本不卡一区二区三区 | 九九热在线观看视频 | 精品国产一区二区三区性色 | 亚洲欧美中文日韩在线v日本 | 国产一区三区在线 | 国产成人精品亚洲日本在线观看 |