Spark內(nèi)存管理

前言

Spark作為一個(gè)基于內(nèi)存的分布式計(jì)算引擎,程序在運(yùn)行時(shí)可能會(huì)被集群中的任何資源阻塞:CPU | 網(wǎng)絡(luò)帶寬 | 內(nèi)存。然而Spark的內(nèi)存管理模塊在整個(gè)系統(tǒng)中扮演著非常重要的角色。理解Spark內(nèi)存管理的基本原理鸭叙,有助于更好地開(kāi)發(fā)Spark應(yīng)用程序和進(jìn)行性能調(diào)優(yōu)

在提交一個(gè)Spark Application時(shí)韧骗,Spark集群會(huì)啟動(dòng)Driver和Executor兩種JVM進(jìn)程驼侠。Driver為主控進(jìn)程兔院,負(fù)責(zé)創(chuàng)建Context殖卑,提交Job,并將Job轉(zhuǎn)化成Task秆乳,協(xié)調(diào)Executor間的Task執(zhí)行懦鼠。而Executor主要負(fù)責(zé)執(zhí)行具體的計(jì)算任務(wù),將結(jié)果返回Driver屹堰。由于Driver的內(nèi)存管理比較簡(jiǎn)單,和一般的JVM程序區(qū)別不大街氢,本文基于Spark2.12重點(diǎn)分析Executor的內(nèi)存管理扯键。

??? 既然說(shuō)到內(nèi)存管理,接下來(lái)不得不說(shuō)Spark任務(wù)開(kāi)啟后涉及的有哪些內(nèi)存I核唷H傩獭!

堆內(nèi)存(on-heap)和堆外內(nèi)存(off-heap)

  • 堆內(nèi)存(on-heap):

描述:在JVM堆上分配的內(nèi)存伦乔,在GC范圍內(nèi)
①:Driver堆內(nèi)存:通過(guò)--driver-memory 或者spark.driver.memory指定厉亏,默認(rèn)大小1G;
②:Executor堆內(nèi)存:通過(guò)--executor-memory 或者spark.executor.memory指定烈和,默認(rèn)大小1G

  • 堆外內(nèi)存(off-heap):

描述:在JVM之外分配的內(nèi)存爱只,不在GC范圍內(nèi)
①:Driver堆外內(nèi)存:通過(guò)spark.driver.memoryOverhead指定,默認(rèn)是Driver堆內(nèi)存的0.1倍招刹,最小是384MB恬试;

Driver堆外內(nèi)存 = max(Driver堆內(nèi)存 * MEMORY_OVERHEAD_FACTOR ,MEMORY_OVERHEAD_MIN  )
注:MEMORY_OVERHEAD_FACTOR = 0.10 和  MEMORY_OVERHEAD_MIN = 384 如有需要的同學(xué)可以查看源碼

②:Executor堆外內(nèi)存 :通過(guò)spark.executor.memoryOverhead指定疯暑,默認(rèn)是Executor堆內(nèi)存的0.1倍训柴,最小是384MB;

Executor堆外內(nèi)存 = max(Executor堆內(nèi)存 * MEMORY_OVERHEAD_FACTOR 妇拯,MEMORY_OVERHEAD_MIN )
注:MEMORY_OVERHEAD_FACTOR = 0.10 和  MEMORY_OVERHEAD_MIN = 384 如有需要的同學(xué)可以查看源碼
  • Driver和Executor內(nèi)存:

①:Driver內(nèi)存大谢媚佟:Driver的堆內(nèi)存 + Driver的堆外內(nèi)存
②:Executor內(nèi)存大小:Executor的堆內(nèi)存 + Executor的堆外內(nèi)存

??? 走到這,大家應(yīng)該對(duì)Spark中涉及的內(nèi)存概念有一個(gè)簡(jiǎn)單的印象了仗嗦,那在開(kāi)發(fā)中我們給Spark任務(wù)一些資源后预麸,它是怎么管理這些內(nèi)存的呢?儒将?吏祸?

內(nèi)存空間分配

  • 靜態(tài)內(nèi)存管理

在靜態(tài)內(nèi)存管理機(jī)制下,存儲(chǔ)內(nèi)存钩蚊,執(zhí)行內(nèi)存和其它內(nèi)存三部分的大小在Spark應(yīng)用運(yùn)行期間是固定的贡翘,但是用戶可以在提交Spark應(yīng)用之前進(jìn)行配置。如果開(kāi)發(fā)者不熟悉Spark的存儲(chǔ)機(jī)制砰逻,或沒(méi)有根據(jù)具體的數(shù)據(jù)規(guī)模和計(jì)算任務(wù)做相應(yīng)的配置鸣驱,很容易會(huì)造成資源沒(méi)有得到合理的分配導(dǎo)致Spark任務(wù)失敗。由于新的內(nèi)存管理機(jī)制的出現(xiàn)蝠咆,靜態(tài)內(nèi)存管理不在本文做詳細(xì)介紹踊东,有興趣的同學(xué)可以參考網(wǎng)上的其它博客。

  • 統(tǒng)一內(nèi)存管理

Spark 1.6之后引入了統(tǒng)一內(nèi)存管理機(jī)制刚操,與靜態(tài)內(nèi)存管理的區(qū)別在于存儲(chǔ)和執(zhí)行內(nèi)存共享同一塊空間闸翅,可以動(dòng)態(tài)占用對(duì)方的空閑區(qū)域。

堆內(nèi)模型

描述:Executor內(nèi)運(yùn)行的并發(fā)任務(wù)共享JVM對(duì)內(nèi)內(nèi)存菊霜。

  • Execution內(nèi)存:主要用于存放Shuffle坚冀,Join,Sort鉴逞,Aggregation等計(jì)算過(guò)程中的臨時(shí)數(shù)據(jù)记某;
  • Storage內(nèi)存:主要用于存放Spark的cache數(shù)據(jù),例如:RDD的緩存构捡,unroll數(shù)據(jù)液南;
  • 用戶內(nèi)存(User Memory):主要用于儲(chǔ)存RDD轉(zhuǎn)換操作所需要的數(shù)據(jù),例如RDD依賴等信息勾徽;
  • 預(yù)留內(nèi)存(Reserved Memory):系統(tǒng)預(yù)留內(nèi)存滑凉,會(huì)用來(lái)存儲(chǔ)Spark內(nèi)部對(duì)象。


    JVM On-heap Memory
  • systemMemory:其實(shí)就是通過(guò)參數(shù)spark.executor.memory 或 --executor-memory配置的捂蕴,在源碼中可以發(fā)現(xiàn)譬涡,systemMemory也有其最小值:minSystemMemory = (reservedMemory * 1.5),也就是最小是reservedMemory的1.5倍啥辨;
/**
   * Return the total amount of memory shared between execution and storage, in bytes.
   */
  private def getMaxMemory(conf: SparkConf): Long = {
    val systemMemory = conf.get(TEST_MEMORY)
    val reservedMemory = conf.getLong(TEST_RESERVED_MEMORY.key,
      if (conf.contains(IS_TESTING)) 0 else RESERVED_SYSTEM_MEMORY_BYTES)
     //SystemMemory最小值
    val minSystemMemory = (reservedMemory * 1.5).ceil.toLong
    if (systemMemory < minSystemMemory) {
      throw new IllegalArgumentException(s"System memory $systemMemory must " +
        s"be at least $minSystemMemory. Please increase heap size using the --driver-memory " +
        s"option or spark.driver.memory in Spark configuration.")
    }
    // SPARK-12759 Check executor memory to fail fast if memory is insufficient
    if (conf.contains(config.EXECUTOR_MEMORY)) {
      val executorMemory = conf.getSizeAsBytes(config.EXECUTOR_MEMORY.key)
      if (executorMemory < minSystemMemory) {
        throw new IllegalArgumentException(s"Executor memory $executorMemory must be at least " +
          s"$minSystemMemory. Please increase executor memory using the " +
          s"--executor-memory option or ${config.EXECUTOR_MEMORY.key} in Spark configuration.")
      }
    }
    //usableMemory計(jì)算邏輯
    val usableMemory = systemMemory - reservedMemory
    val memoryFraction = conf.get(config.MEMORY_FRACTION)
    (usableMemory * memoryFraction).toLong
  }
  • reservedMemory:其值等于300MB涡匀,這個(gè)值平常線上開(kāi)發(fā)是不做修改的;
// Set aside a fixed amount of memory for non-storage, non-execution purposes.
  // This serves a function similar to `spark.memory.fraction`, but guarantees that we reserve
  // sufficient memory for the system even for small heaps. E.g. if we have a 1GB JVM, then
  // the memory used for execution and storage will be (1024 - 300) * 0.6 = 434MB by default.
  private val RESERVED_SYSTEM_MEMORY_BYTES = 300 * 1024 * 1024
  • usableMemory = systemMemory - reservedMemory溉知,這個(gè)就是Spark的可用內(nèi)存陨瘩,具體可以在上面介紹systemMemory中找到這個(gè)值怎么計(jì)算的腕够。
堆外模型

描述:相比對(duì)內(nèi)內(nèi)存,堆外內(nèi)存的模型比較簡(jiǎn)單舌劳,只包括Storage內(nèi)存和Execution內(nèi)存帚湘,其分布如下圖:

Off-heap Memory

??? 上面大概說(shuō)了說(shuō)Spark中的堆內(nèi)存和堆外內(nèi)存怎么管理以及相關(guān)參數(shù)怎么得到和設(shè)置的,其中涉及了Execution和Storage內(nèi)存動(dòng)態(tài)占用的情景甚淡,那接下來(lái)聊一聊動(dòng)態(tài)占用機(jī)制是怎么樣的大诸??
動(dòng)態(tài)占用機(jī)制
  • Execution內(nèi)存不夠用的時(shí)候贯卦,可以去Storage內(nèi)存中申請(qǐng)使用资柔;
  • Storage內(nèi)存不夠用的時(shí)候也可以去Execution區(qū)域中聲明使用;
  • 但是Storage內(nèi)存在使用完占用的Execution內(nèi)存之后撵割,需要?dú)w還對(duì)方的內(nèi)存贿堰,而Execution內(nèi)存在使用完Storage內(nèi)存是默認(rèn)是不歸還的。
動(dòng)態(tài)占用

>>本篇文章僅僅記錄自己的學(xué)習(xí)過(guò)程啡彬,文章中如有錯(cuò)誤或不妥之處羹与,請(qǐng)留言,謝謝庶灿!<<
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末纵搁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子跳仿,更是在濱河造成了極大的恐慌诡渴,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件菲语,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惑灵,警方通過(guò)查閱死者的電腦和手機(jī)山上,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)英支,“玉大人佩憾,你說(shuō)我怎么就攤上這事「苫ǎ” “怎么了妄帘?”我有些...
    開(kāi)封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)池凄。 經(jīng)常有香客問(wèn)我抡驼,道長(zhǎng),這世上最難降的妖魔是什么肿仑? 我笑而不...
    開(kāi)封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任致盟,我火速辦了婚禮碎税,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘馏锡。我一直安慰自己雷蹂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布杯道。 她就那樣靜靜地躺著匪煌,像睡著了一般。 火紅的嫁衣襯著肌膚如雪党巾。 梳的紋絲不亂的頭發(fā)上萎庭,一...
    開(kāi)封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音昧港,去河邊找鬼擎椰。 笑死,一個(gè)胖子當(dāng)著我的面吹牛创肥,可吹牛的內(nèi)容都是我干的达舒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼叹侄,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼巩搏!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起趾代,我...
    開(kāi)封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贯底,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后撒强,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體禽捆,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年胚想,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浊服。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胚吁,死狀恐怖牙躺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情腕扶,我是刑警寧澤孽拷,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布蕉毯,位于F島的核電站思犁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏进肯。R本人自食惡果不足惜激蹲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望江掩。 院中可真熱鬧,春花似錦环形、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至钙畔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間擎析,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工桨醋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留现斋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓步责,卻偏偏與公主長(zhǎng)得像禀苦,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔗包,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容