我们在Scala中运行Spark 2.2作业,在YARN集群中运行,执行以下操作:
-
将几千个小的压缩拼花文件(每个约15kb)读入两个数据帧
-
将数据帧加入一列
-
折叠所有列以清理一些数据
-
删除重复项
-
将结果数据写入镶木地板
以下配置通过java.lang.OutOfMemory java堆空间失败:
-
--conf spark.yarn.am.memory = 4g
-
--conf spark.executor.memory=20g
-
--conf spark.yarn.executor.memoryOverhead = 1g
-
--conf spark.dynamicAllocation.enabled = true
-
--conf spark.shuffle.service.enabled = true
-
--conf spark.dynamicAllocation.maxExecutors = 5
-
--conf spark.executor.cores = 4
-
--conf spark.network.timeout = 2000
但是,如果我们完全删除 spark.executor.memory ,这项工作可靠 . 这给每个执行者1g的ram .
如果我们执行以下任何操作,此作业也会失败:
-
增加执行者
-
增加默认并行度或spark.sql.shuffle.partitions
任何人都可以帮助我理解为什么更多的内存和更多的执行程序会导致OutOfMemory失败的工作?
1 回答
手动设置这些参数会禁用dynamic allocation . 尝试不管它,因为它建议初学者使用 . 在您可以在PROD设置中微调簇大小之前,它对于实验也很有用 .
在Spark中投入更多内存/执行程序似乎是一个好主意,但在您的情况下,它可能会导致额外的混乱和/或降低HDFS I / O吞吐量 . 这个article虽然稍微过时并且面向Cloudera用户,但他解释了如何通过正确调整执行程序来调整并行性 .