Spark内存管理

Spark内存管理

1、介绍

spark内存管理不是通过物理或者硬件底层API实现对内存资源探测,只是通过对内存操作过程期间的字节量的变化不断更新维护的数字,通过该方式跟踪内存使用情况。spark对每个task都关联了内存的使用量,存放在了map<Long,Long>中。严格意义上讲,spark内存的管理是估算量,不是精确量。spark的内存管理主要针对的堆内内存,和离堆非堆无关。

2、Spark内存结构

spark内存是指jvm的堆内存,也称为系统内存。系统内存必须是保留内存的1.5倍以上。由于保留内存默认是300m,因此spark系统内存必须是450m空间以上。

2.1 系统内存设置

  1. 启动命令设置

    $>spark-submit --executor-memory 500m
    
  2. 属性配置设置

    conf.set("spark.executor.memory" , 500 * 1024 * 1024 + "")
    

2.2 系统内存结构

系统内存分为如下几个部分:

  • 保留内存

    硬编码设置空间大小为300m,供spark使用。可以通过如下两个属性关闭或改变大小:

    #设置保留内存
    $>spark-shell --conf spark.testing.reservedMemory=0
    
    #关闭保留内存
    $>spark-shell --conf spark.testing=1	
    
  • 可用内存

    可用内存空间是系统内存 - 保留内存,内部分为用户内存和spark内存。

    • 用户内存

      用户内存没有直接设置的参数,是通过给spark内存设置内存比例参数,剩余的就是用户内存。因此

      spark.memory.fraction默认是0.6。存储RDD变换的自定义数据结构。

      用户内存 = (1 - spark.memory.fraction) * 可用内存
      
    • spark内存

      spark内存占用可用内存的比例是多少通过参数spark.memory.faction(默认0.6)控制。

      #设置spark内存占可用内存比例
      $>spark-submit --conf spark.memory.faction 0.7 ...
      
      • 存储内存

        存储内存通过设置占用spark内存比例完成,属性为spark.memory.storage.faction(默认0.5)。存放缓存数据和串行化数据,以及所有的广播变量也以缓存block方式存放在该区域中。

        #设置存储内存占用spark内存比例
        $>spark-submit --conf spark.memory.storage.faction 0.6 ...
        
      • 执行内存

        执行内存没有指定的参数,确定了存储内存后,剩余的空间就是执行内存。存放task执行期间需要的对象,比如map端shuffle的中间数据buffer,再有就是hash聚合时的hashtable。该部分内存也支持内存不足时spill到磁盘,但是该内存中的block不能被其他线程强制移除。

        执行内存 = (1 - spark.memory.storage.faction) * spark内存
        

3、内存管理

spark的内存有StaticMemoryManager(静态内存管理)和UnifiedMemoryManager(统一内存管理)。

  • StaticMemoryManager

    spark存储内存和执行内存之间不能互相借用,有着严格分界线。是传统模式的内存管理模型。

  • UnifiedMemoryManager

    执行内存和存储之间有借用区域,存储内存借用执行内存的时候,如果执行内存不足,可以收回,最多收回借出的部分,不能到对方去抢内存。反之执行内存借用存储内存时,如果存储不足,收不回借出的内存,原因是算法实现比较复杂。

posted @ 2018-08-27 20:44  大道至简(老徐)  阅读(443)  评论(0编辑  收藏  举报