spark调优-JVM调优+Shuffle调优

          JVM调优:

1 降低cache操作的内存占比

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

默认情况下,给RDD cache操作的内存占比,是0.6,60%的内存都给了cache操作了。但是问题是,如果某些情况下cache不是那么的紧张,问题在于task算子函数中创建的对象过多,然后内存又不太大,导致了频繁的minor gc,甚至频繁full gc,导致spark频繁的停止工作。性能影响会很大。

2 调节executor堆外内存与连接等待时长

调节executor堆外内存

       有时候,如果你的spark作业处理的数据量特别大,几亿数据量。然后spark作业一运行,时不时的报错,shuffle file cannot find,executor、task lost,out of memory(内存溢出)。可能是executor的堆外内存不太够用,导致executor在运行的过程中,可能会内存溢出,可能导致后续的stage的task在运行的时候,要从一些executor中去拉取shuffle map output文件,但是executor可能已经挂掉了,关联的block manager也没有了。所以会报shuffle output file not found,resubmitting task,executor lost。spark作业彻底崩溃。上述情况下,就可以去考虑调节一下executor的堆外内存。也许就可以避免报错。此外,有时堆外内存调节的比较大的时候,对于性能来说,也会带来一定的提升。

可以调节堆外内存的上限:

--conf spark.yarn.executor.memoryOverhead=2048

调节连接等待时长

我们知道,executor会优先从自己本地关联的BlockManager中获取某份数据。如果本地block manager没有的话,那么会通过TransferService,去远程连接其他节点上executor的block manager去获取。

而此时上面executor去远程连接的那个executor,因为task创建的对象特别大,特别多,

频繁的让JVM堆内存满溢,正在进行垃圾回收。而处于垃圾回收过程中,所有的工作线程全部停止,相当于只要一旦进行垃圾回收,spark / executor停止工作,无法提供响应。

此时呢,就会没有响应,无法建立网络连接,会卡住。spark默认的网络连接的超时时长,是60s,如果卡住60s都无法建立连接的话,那么就宣告失败了。

报错几次,几次都拉取不到数据的话,可能会导致spark作业的崩溃。也可能会导致DAGScheduler,反复提交几次stage。TaskScheduler反复提交几次task。大大延长我们的spark作业的运行时间。

可以考虑调节连接的超时时长:

--conf spark.core.connection.ack.wait.timeout=300

Shuffle调优

1 合并map端输出文件,方法:开启shuffle map端输出文件合并机制

new SparkConf().set("spark.shuffle.consolidateFiles", "true")

默认情况下,是不开启的,就是会发生如上所述的大量map端输出文件的操作,严重影响性能。

2 调节map端内存缓冲与reduce端内存占比

默认reduce占比0.2  map站0.8,大家想想看如果reduce拉去过来的数据很大,内存很小,一次读不完,只能缓存到磁盘,然后再去磁盘读,产生大量IO消耗,所以可以调节reduce的内存占比,把map的shuffle溢写32k调大

调节map task内存缓冲:spark.shuffle.file.buffer,默认32k(spark 1.3.x不是这个参数,后面还有一个后缀,kb。spark 1.5.x以后,变了,就是现在这个参数)

调节reduce端聚合内存占比:spark.shuffle.memoryFraction,0.2

3 合理使用hashshuffleManager(spark1.2之前默认的)跟sortShuffleManager(spark1.2之后默认的)

3.1、需不需要数据默认就让spark给你进行排序?就好像mapreduce,默认就是有按照key的排序。如果不需要的话,其实还是建议搭建就使用最基本的HashShuffleManager,因为最开始就是考虑的是不排序,换取高性能。

3.2、什么时候需要用sort shuffle manager?如果你需要你的那些数据按key排序了,那么就选择这种吧,而且要注意,reduce task的数量应该是超过200的,这样sort、merge(多个文件合并成一个)的机制,才能生效把。但是这里要注意,你一定要自己考量一下,有没有必要在shuffle的过程中,就做这个事情,毕竟对性能是有影响的。

3.3、如果你想选用sort based shuffle manager,而且你们公司的spark版本比较高,是1.5.x版本的,那么可以考虑去尝试使用tungsten-sort shuffle manager。看看性能的提升与稳定性怎么样。

总结:

-->   如果你不想要你的数据在shuffle时排序,那么就自己设置一下,用hash shuffle manager。

-->   如果你的确是需要你的数据在shuffle时进行排序的,那么就默认不用动,默认就是sort shuffle manager。或者是什么?如果你压根儿不care是否排序这个事儿,那么就默认让他就是sort的。调节一些其他的参数(consolidation机制)。(80%,都是用这种)

 

 

 

 

猜你喜欢

转载自blog.csdn.net/qq_32736999/article/details/84022458