我们的Spark环境目前主要问题是数据量大后一些task的GC Time 特别长,多则几分钟,少则几十秒,实在不能忍受。参考databricks的Tuning Java Garbage Collection for Spark Applications对我们的环境优化后,效果比较明显。
如果分配给单个Executor的Heap足够大(我认为超过32G)时使用G1,否则使用Parallel。因为如果在Heap小于32G时使用G1,G1 region size默认小于16M,可能引发Humongous对象分配问题。
当然,使用G1可能也可能引起Executor异常退出,这时有两种解决方法:
1. 减少cores数量(就是减少当前Executor并行task的数量)
2. 增加老年代内存
硬件环境:(64G+8cores+42T) * 4,用yarn管理,利用Spark SQL对124G,169个字段的数据用row_number函数除重,除重前1.6亿条,除重后1.5亿条:
executor-memory | executor-cores | extraJavaOptions | Max GC Time | Job Duration |
---|---|---|---|---|
20g | 10 | -XX:+UseG1GC | 60s | 32min |
30g | 20 | -XX:+UseG1GC | 2.0 min | 27min |
36g | 20 | -XX:+UseG1GC | 1.8 min | 26min |
36g | 20 | -XX:+UseG1GC -XX:NewRatio=8 | 11 s | 23min |
36g | 22 | -XX:+UseG1GC -XX:NewRatio=8 | 17 s | 25min |
36g | 28 | -XX:+UseG1GC -XX:NewRatio=8 -XXConcGCThreads=20 | 28 s | 22min |
20g | 20 | -XX:+UseParallelGC -XX:+UseParallelOldGC | 50s | 25min |
36g | 20 | -XX:+UseParallelGC -XX:+UseParallelOldGC | 17s | 25min |
20g | 20 | -XX:+UseConcMarkSweepGC -XX:+UseParNewGC | 1.9min | 42min |
36g | 20 | -XX:+UseConcMarkSweepGC -XX:+UseParNewGC | 1.7min | 34min |
当内存比较小,在测试时也遇到了databricks遇到的两个问题。我们之前使用CMS的,现在改为G1,由之前的34min降为23min,性能提升还是比较明显的。
参考文档:
http://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html
联系客服