Spark调优 JVM调优

版权声明:本文为博主九师兄(QQ群:spark源代码 198279782 欢迎来探讨技术)原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21383435/article/details/80468772

1. 为什么要进行JVM调优?为什么要进行垃圾回收?

这里写图片描述

Spark是由Scala写的,而Java和Scala都是运行在JVM上的。而一个executor就是一个JVM进程。

我们会把executor分成两份,老年代和新生代,比例可能会不一样。新生代会分成三份。

这里写图片描述

Spark作业开始运行,会不断的产生对象,对象会首先进入Eden区,然后如果Eden区存储满了,对象就会进入survivor1区,如果Eden和survivor1区都满了,就会发生minor GC,h会在新生代里面发生垃圾回收,,把不需要的对象回收。假设4,7,8都是无用的对象会被清除,而5,6是没被GC掉的,就会被放到9中。如果左边都不够用了,就会把survivor中的放入老年代里。如果一个对象,在新生代,多次minor GC 还是没有被回收,那么说明这个对象是长时间存活的对象,那么就会把这些对象移动到老年代里。如果一直这么移动,如果老年代也存不下对象,那么就会发生full GC,full GC非常耗费资源。

不正常的情况。如果Eden区不够大,那么很可能出现大量的数据频繁进入survivor区,那么会平凡的进入老年代,full GC就会很频繁的发生,会导致Spark工作现场停止,直接影响Spark作业的运行。

如果Eden区比较小,会很快满,然后survivor也会变满,最后老年代会有很多存活时间短的对象,导致full GC.

这里写图片描述

2.基础调优思路

垃圾回收的性能开销,是跟内存中的对象的数量成正比的。
1. 对于垃圾回收的性能问题,首先要做的就是,使用高效的数据结构。
2. 持久化RDD时,使用序列化的持久化级别,而且使用Kyro序列化类库,这样partition就只是一个对象,一个字节数组
3. 给Eden区域分配更大的空间,使用-Xmn即可,通常建议给Eden区域,预计大小的4/3

如果使用的是HDFS文件,那么很好估计Eden区域的大小,如果每个executor有4个task,然后每个hdfs压缩块解压缩后大小是3倍,此外每个hdfs块的大小是64M,那么Eden区域的预计大小就是:4*3*64M,然后通过-Xmn参数,将Eden区域的大小设置为4*3*64*3/4

3.大数据启动的JVM进程

hadoop
    hdfs
        NameNode
        datenode
    YARN
        ResourceManager
        NodeManager
Hbase
    Hmaster
    HRegionserver
Spark
    Master
    Worker

都是Java虚拟机服务进程(JVM)

4.CDH版本的Spark默认优化

这些参数是多次试验后得到的数据,注意这个是虚拟机的,实际需要修改。

-Xms1073741824 -Xmx1073741824
-XX:+UseParNewGC    -XX:+useConcMarkSweepGC -XX:-CMSConcurrentMTEnabled
-XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled
-XX:OnOutOfMemoryError=/usr/lib64/cmf/service/common/killparent.sh

解释

-Xmx:最大堆的大小 (生产环境-Xmx会设置大点)
-Xms : 初始堆大小
-XX:+UseConcMarkSweepGC 该标志首先激活CMS收集器,默认HotSpot JVM是的是并行收集器。
-XXUseParNewGC:当使用CMS收集器时,该标志激活年轻代使用多多线程并行执行垃圾回收。
-XX:+CMSConcurrentMTEnabled 该标志被启用时,并发的CMS阶段将以多线程执行(因此,多个GC会与所有的应用程序并行工作)该标志已经默认开如果顺序执行更好,这取决于所使用的硬件。多线程执行可以通过-XX:CMSConcurrentMTEnabled禁用。
-XX:+CMSParllelRemarkEnabled:降低标记停顿

+号是开启  -是关闭

CMSInitiatingOccupancyFraction:使用cms作为垃圾回收使用70%后开始CMS收集

当我们的年老代内存占用70%,就进行垃圾回收。

-XX:+CMSConcurrentMTEnabed:当该标志被启动时,并发和CMS阶段将以多线程执行(因此,多个GC线程会与所有的应用程序并行工作)。该标志已经默认开启,如果顺序执行更好,这取决于所使用的的硬件,多线程执行可以通过-XX:-CMSConcurremntMTEnabled禁用。
-XX:+CMSParallelRemarkEnabled:降低标记停顿

参考:
JVM体系
GC常见的算法

展开阅读全文

没有更多推荐了,返回首页