Memory Tuning

- 1 min

Memory Tuning

在内存调优中,通常有三点需要考虑:

默认情况下,对java的对象的访问时非常快的,但也因此比对象本身裸数据量消耗更多的内存(2~5倍不等)。这是由以下几个原因造成的:

该笔记会先对Spark中的内存管理进行一个概述,然后介绍一些特殊的用来优化应用程序的内存使用的策略。另外,还将介绍如何来决定用户对象的内存使用的经验以及如何通过修改用户数据的数据结构或者通过序列化格式来优化它们。最后还将介绍一些spark cache size和java GC方面的经验。

Memory Management Overview

在Spark中内存的消耗通常在两个方面:executionstorage。Execution memory指的是在计算中用于做shuffle, sorts和aggregations的内存,而Storage memory指的是用来做cache和在cluster内传播数据的内存。在Spark中,execution和storage共享一个统一个内存空间(unified region - M)。当没有execution内存使用的时候,storage可以使用所有的空闲内存用来做cache,反之亦然。Exxcution在必要的时候有可能会释放storage内存,但仅仅会在所有的storage内存的使用率低于某一个阈值(R)之后才会这么做。而storage不会释放execution的内存。

这种设计是为了达到几种目的:

有两个选项能够对spark作业的内存管理进行配置(通常情况下使用期默认配置即可):

spark.memory.fraction的配置需要设置的跟JVM的OLD或者“tunured generation”匹配。否则,当大部分的内存用来做caching和execution时,JVM的tenured generation有可能会满,从而导致JVM进行频繁的GC。这里可以参考Java GC sizing documentation

Tenured generation size是由JVM的NewRatio参数来设置的,默认为2,表示tenured generation是new generation的2倍大小。所以,默认情况下,tenured generation占据了2/3或者67%左右的JVM heap size。

A value of 0.6 for spark.memory.fraction keeps storage and execution memory within the old generation with room to spare. If spark.memory.fraction is increased to, say, 0.8, then NewRatio may have to increase to 6 or more.

NewRatio is set as a JVM flag for executors, which means adding spark.executor.extraJavaOptions=-XX:NewRatio=x to a Spark job’s configuration.

Determing Memory Consumption

Tunning Data Structures

Serialized RDD Storage

Garbage Collection Tuning

comments powered by Disqus
rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora