spark 内存模型以及垃圾回收优化

1.6版本内存模型

1.6之前的版本是一个静态的内存模型,executor中分成三个部分,一部分是Execution区域,一部分是Storage内存区域,还有是预留的其他给spark的内部使用的区域,在spark的configuration中默认的有以下参数控制。

spark.storage.memoryFraction: 默认0.6

spark.shuffle.memoryFraction: 默认0.2

Storage内存模型这一部分主要是处理cache操作和广播变量这些。
Execution就是执行map,join,reduce等这些任务的。

那么我们为啥要知道这个呢?就是我们想一个事情,如果假如我们的代码中有shuffle操作,我们都是shuffle,而且其中有一个key的值非常大,我们就需要Execution的内存要大,但是不要意思,只给他分配了0.2,这个时候会出现什么问题呢?毫无疑问,在数据量大于0.2的Execution的时候,一定会出现内存溢出的问题。你可能想,storage内存那么大,我能不能用一些呢?不好意思,不可以,这就是静态模型,也就是静态模型中,storage的内存部分和Execution内存部分不能相互借用,所以这里就是优化点,也就是假如我们运行的代码在spark1.6版本之前的话,我们运行之前就要先想好到底是storage需要的多还是Execution多,我们手动的指定,读到这里,你是不是觉得非常不方便?是的,非常麻烦。于是我们就引入我们的统一内存模型

2.0版本统一内存模型

统一静态模型,系统预留300M,然后把剩余内存整体划分为两个部分,由spark.memory.fraction这个指定默认值是0.6,另外一部分是0.4,然后spark.memory.fraction这部分又划分两个小部分,这两个小部分整体占用0.6,这两份其实就是storage内存和execution内存。上面我们说静态模型的时候,提到storage和execution不能互相借用,但是在这里他们可以相互借用

垃圾回收优化

如果发现,在task执行期间,大量full gc 发生了 ,那么说明,年轻代的Survivor区域,给的空间不够大,此时可以执行一些操作来优化垃圾回收行为:
1.包括降低spark.storage.memoryFraction的比例,给年轻代更多的空间,来存放短时间存活的对象;
2.给Eden 区域分配更大的空间,使用-Xmm即可 ,通常建议给Eden 区域,预计大小的4/3;
3.如果使用的是HDFS文件,那么很好估计Eden区域大小,如果executor有4个task.然后每个hdfs压缩块 解压缩后大小是3倍,此外每个hdfs块的大小是64m,那么Eden区域的预计大小就是:4364MB.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容