Spark性能调优 (六)---JVM调优之原理概述及降低cache操作的内存占比

1.原理概述

1.1理论

Spark是用Scala开发的。Spark的Scala代码调用了很多java api。Scala也是运行在JVM中的,所以Spark也是运行在JVM中的。

1.2JVM可能会产生的问题

      内存不足——RDD的缓存、task运行定义的算子函数,可能会创建很多对象,占用大量的内存。处理不当,可能导致JVM出问题。

1.3堆内存

作用:存放项目中创建的对象。
划分:新生代(young generation,Eden区域+survivor区域1+survivor区域2,比例8:1:1),老年代(old generation)

1.4GC(垃圾回收)

       每次创建出来的对象,都会放到Eden区域和survivor区域1中,另外一个survivor区域空闲。

       由于spark作业产生的对象过多,当Eden区域和survivor区域放满之后,就会触发minor gc(初代回收)。把不再使用的对象从内存中清理出去,给后面对象的创建腾出空间。

      清理掉了不再使用的对象之后,那些存活下来(还需要继续使用)的对象,放入之前空闲的survivor区域2中。当survivor区域2满了放不下,JVM会通过担保机制机制将多余的对象直接放到老年代中。

       如果JVM内存不够大,可能导致频繁的新生代内存溢出,频繁的minor gc。频繁的minor gc会导致短时间内,有些存活下来的对象,经过多次垃圾回收都没有回收掉,导致这种生命周期短(不一定会长期使用)的对象,年龄过大,进入老年代。

      老年代中存在过多的短生命周期的、本该在新生代中可能马上要被回收的对象,导致内存不足,频繁内存满溢,频繁进行full gc(老年代回收)。full gc会回收老年代中的对象。由于老年代中的对象数量少,满溢进行的full gc频率本应该很少,所以回收算法很简单,但是耗费性能和时间。——full gc很耗时间。

      full gc/minor gc,无论快慢,都会导致JVM工作线程停止工作,spark作业会暂停,等待垃圾回收完成之后继续工作。

1.5总结---内存不足导致的问题

频繁minor gc,导致spark频繁停止工作
老年代囤积大量活跃对象(短生命周期的对象),导致频繁full gc,full gc时间很长,短则数十秒,长则数十分钟,甚至数小时,导致spark长时间停止作业
严重影响spark作业的性能和运行的速度

2.降低cache操作的内存占比

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

       默认情况下,给RDD cache操作的内存占比是0.6,但是可能cache真正需要使用的内存不需要这么多,而存储spark算子函数创建对象需要大量的内存,这个时候可以调节这个参数,比如0.5、0.3、0.2等等。

       用yarn运行spark的时候,通过yarn页面可以查看spark作业的运行统计,一层一层点进去,可以看到每个stage的运行情况,包括每个task的运行时间、gc时间等。根据情况,如果gc频繁,时间太长,可以适当地调整这个比例,反复测试,直到调整到一个合适的比例。

      在spark的代码中设置示例:SparkConf.set("spark.storage.memoryFraction","0.6")
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值