Spark之jvm调优

一、spark内存模型

Spark1.6之前使用的内存模型是StaticMemoryManager实现,1.6之后使用UnifiedMemoryManager实现。

spark支持用参数spark.memory.useLegacyMode来配置使用哪种内存管理模式。

Executor内存使用

(1)RDD存储

当调用RDD的persist或者cache时,RDD的分区会被存储到内存里

(2)shuffle

需要用缓存区存储shuffle的输出和聚合的中间结果

(3)用户代码

编写的代码使用的内存是整个堆除了RDD存储和shuffle之外剩余的空间

 

1、StaticMemoryManager内存模型

(1)如果spark作业中有较多的RDD持久化操作,则可以将spark.storage.memoryFraction调大点,保证持久化的数据能在内存中容纳,避免内存不够缓存所有数据,导致数据只能写入磁盘,降低性能

(2)如果spark作业shuffle操作较多,则可以将spark.shuffle.memoryFraction调大点,避免shuffle过程中数据过多内存不足溢写到磁盘,降低性能。

(3)如果spark作业频繁GC,task运行的用户代码内存不够,可以适当降低spark.storage.memoryFraction和spark.shuffle.memoryFraction的值。

 

2、UnifiedMemoryManager内存模型

(1)如果spark作业中有较多的RDD持久化操作,则可以将spark.storage.memoryFraction调大点,保证持久化的数据能在内存中容纳,避免内存不够缓存所有数据,导致数据只能写入磁盘,降低性能

(2)如果spark作业shuffle操作较多,则可以将spark.storage.memoryFraction调低点,避免shuffle过程中数据过多内存不足溢写到磁盘,降低性能。

(3)如果spark作业频繁GC,task运行的用户代码内存不够,可以适当降低spark.storage.memoryFraction的值。

 

二、jvm内存优化

1、RDD使用序列化后再持久化

垃圾回收的开销和对象个数成正比,所以减少对象个数,可以减少垃圾回收的开销。最好的方式是使用序列化的方式存储数据,这是每个RDD分区只包含一个对象(一个巨大的字节数组)。

spark默认情况下使用60%的空间用于持久化,40%用于task执行代码逻辑,如果出现GC,那就需要调整缓存区的参数,或者使用序列化对象后再存储,减少缓存区大小,进而给task更多的空间,避免频繁的GC

2、GC调优

(1)Minor GC出现多次,Full GC出现次数少,适当的给新生代更多的内存,比如Eden内存为E,设置Young区的内存为4/3*E,

这样Eden变大了,同时survivor区也变大了。然后再观察任务运行情况

(2)Old区接近满时,说明缓存的对象多了,此时可以降低缓存空间,最好的方式时缓存更少的对象,比如使用序列化对象再放入缓存中

3、数据源是HDFS

读取HDFS数据解压后的大小是解压前的2~3倍,需要评估下Eden的内存大小,比如设置成3~4倍的工作内存空间

三、jvm的GC导致shuffle拉取文件失败

spark运行的时候出现shuffle拉取文件失败,如shuffle output file lost,正真的原因是GC导致的。

如果GC是Full GC,通常会暂停用户线程,此时下一个stage会默认重试3次拉取数据,每次重试时间5s,即15秒没有拉取到文件,就会报类似shuffle output file lost的异常。

优化方式

(1)调整shuffle的数据重试次数,默认是3次,适当的调大。

(2)调整shuffle数据重试间隔,默认是5秒,适当的调大,参数:spark.shuffle.io.retrywait

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值