Spark性能调优之JVM调优 降低cache操作的内存占比 spark.storage.memoryFraction

理论基础

Spark就是用scala开发的,scala是运行在java虚拟机(JVM)上的,所以Spark也是运行在JVM上,而且Spark的scala代码中也调用了很多java api。这个理论基础很重要! 下面介绍通过调节JVM调节来优化Spark性能。

 

问题背景

JVM中,每次存放创建的对象时,都是先放入Eden区域和其中一个survivor区域;另一个survivor区域是空闲的。(如下图)

当Eden区域和一个survivor区域放满以后(放满是因为Spark运行过程,产生的对象太多了),就会触发minor GC,也就是小型垃圾回收,从内存中清空不再使用的对象。

清理了不再使用的对象后,那么存活下来的对象(还要被继续使用)会被放入之前那个空闲survivor区域。这里可能会出现一个问题:默认Eden、survivor1、survivor2的内存占比是8:1:1,那如果存活下来的对象大于1/10呢,一个survivor区域是放不下的,此时,通过JVM担保机制,将多出来的存活对象,放入老年代。理想状态下,老年代都是存放一些生命周期很长的对象,数量是很少的。比如,数据库连接池。(如下图)

如果JVM内存不够大的话,可能就会导致年轻代内存满溢,触发频繁的minor GC。频繁的minor GC会导致短时间内,有些存活的对象被多次垃圾回收都没有被回收掉,会导致这种短生命周期的对象,年龄过大(每次垃圾回收没被回收掉,年龄就+1),被放到老年代。(如下图)
Spark性能调优之JVM调优 降低cache操作的内存占比 spark.storage.memoryFraction_第1张图片
老年代中,可能会因为内存不足,累积了一大堆、生命周期其实很短的、本来应该在年轻代中的、可能马上会被回收掉的对象,太多的这种对象存在老年代,就可能导致老年代满溢,触发full GC(全局全面垃圾回收)。full GC会去老年代中回收对象。full GC算法设计针对的是老年代中对象少,满溢触发full GC的频率应该低,因此采取了不太复杂、但耗费性能和时间的GC算法。full GC时间很长!

full GC/minor GC,无论快慢,都会导致JVM的工作线程暂时停止工作,Stop the world。也就是说,GC时,Spark停止工作了,等GC完成后,再开始Spark作业。后果很严重!

JVM内存不足的时候,会导致:

  1. 频繁minor GC,也会导致频繁Spark停止工作;
  2. 老年代累积了大量的活跃对象(短生命周期的对象),导致满溢触发full GC,full GC时间很长(短则数十秒,长则数分钟,甚至数小时),Spark长时间停止工作。

解决方法:

降低JVM中cache操作所占的内存占比。

Spark中,堆内存被划分为两块:一块是专门用来给RDD的cache、persist操作进行数据缓存用的;另一块是用来给Spark算子函数运算使用的,来存放算子函数中创建的对象。

默认配置中,RDD的cache、persist所占内存的60%。但在某些情况下,RDD的cache、persist所需内存并不是那么紧张;而在task算子函数中创建的对象却太多,内存存不下,触发频繁minor GC,甚至full GC,就会导致了Spark频繁的停止工作,这对Spark性能影响很大。

通过Spark ui 观察,可以看到各个stage的运行情况,包括各个task的运行时间、GC时间。如果看到GC太频繁,时间也很长,此时就可以适当调节两块内存的占比。

降低RDD的cache、persist的内存占比,大不了persist(持久化)RDD的时候,写入磁盘,再配合Kyro序列化,目的是减少RDD缓存的内存占比。对应的,算子函数的内存占比就提升了。我们这样考虑,RDD的cache、persist的内存比降低了,RDD写入磁盘而导致磁盘IO。总比Spark因为频繁GC导致Spark长时间停止工作强吧。

  • RDD的cache、persist(持久化) 详见笔者《Spark性能调优之RDD持久化》
  • Kyro序列化 详见笔者《Spark性能调优之Kryo序列化》

总结

一句话,让Spark的task执行算子函数时,有更多内存使用。
这里减少RDD的cache、persist内存占比,相应的,也就增加了Spark算子函数的内存占比。

SparkConf SparkConf = new SparkConf()
						.set(“Spark.storage.memoryFraction”, “0.4”)  // 默认是0.6(60%)

你可能感兴趣的:(Hadoop生态,spark)