因为之前spark程序运算量不是特别大,关于提交时申请的集群资源就一直没有变动,后来数据不断增大,导致程序出现以下异常:
java.lang.OutOfMemoryError: Java heap space
java.lang.OutOfMemoryError:GC overhead limit exceeded
spark属性方面调整:
一般这两个异常是由于executor或者driver内存设置的不够导致的,driver设置过小的情况不过相对较小,一般是由于executoer内存不足导致的。 不过不论是哪种情况,我们都可以通过提交命令或者是spark的配置文件指定driver-memory和executor-memory的内存大小来解决问题。 spark-submit --master yarn-cluster --class MAIN_CLASS --executor-memory 10G --executor-cores 10 --driver-memory 2g --name APP_NAME
代码方面调整建议:
其实当数据量越大时,越能体现出代码质量的重要性,所以出现oom的问题也应该从代码方向看一下是否还有调整优化的空间,特别是针对RDD操作的代码。比如,RDD是否还需要重用进行多次操作,如果是我们就可以使用cache()和persist()选择不同的缓存策略,不但提高下次操作时的执行效率,并且还能节省创建RDD占用的内存。另外Transformation 操作是延迟计算的,也就是说从一个RDD 转换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触发运算。
另外还有算子的选择,例如:mapPartitionsToPair虽然能提高spark的执行效率,但如果数据量过大内存不足在进行算子操作时,也会有可能跑出java heap space异常
另外还有算子内操作尽量能用基本数据类型就不用引用类型,能用数组就不用集合,另外还比如字符串拼接,用StringBuffer代替+连接等等。这些方式不但可以节省空间还能增加算子的执行效率。
博主还是新手,以上均为个人理解,但都是工作中已经实践确认过的,如有错误,欢迎指正。