我在一些Spark LDA主题建模中遇到了各种问题(主要是看似随机间隔的解除错误)我一直在运行,我认为这主要与我执行器上的内存分配不足有关。这似乎与有问题的自动群集配置有关。我的最新尝试使用n1-standard-8机器(8核,30GB RAM)用于主节点和工作节点(6个工作站,因此总共48个核心)。
但是当我看到/etc/spark/conf/spark-defaults.conf
时,我看到了这一点:
spark.master yarn-client
spark.eventLog.enabled true
spark.eventLog.dir hdfs://cluster-3-m/user/spark/eventlog
# Dynamic allocation on YARN
spark.dynamicAllocation.enabled true
spark.dynamicAllocation.minExecutors 1
spark.dynamicAllocation.initialExecutors 100000
spark.dynamicAllocation.maxExecutors 100000
spark.shuffle.service.enabled true
spark.scheduler.minRegisteredResourcesRatio 0.0
spark.yarn.historyServer.address cluster-3-m:18080
spark.history.fs.logDirectory hdfs://cluster-3-m/user/spark/eventlog
spark.executor.cores 4
spark.executor.memory 9310m
spark.yarn.executor.memoryOverhead 930
# Overkill
spark.yarn.am.memory 9310m
spark.yarn.am.memoryOverhead 930
spark.driver.memory 7556m
spark.driver.maxResultSize 3778m
spark.akka.frameSize 512
# Add ALPN for Bigtable
spark.driver.extraJavaOptions -Xbootclasspath/p:/usr/local/share/google/alpn/alpn-boot-8.1.3.v20150130.jar
spark.executor.extraJavaOptions -Xbootclasspath/p:/usr/local/share/google/alpn/alpn-boot-8.1.3.v20150130.jar
但这些价值观没有多大意义。为什么只使用4/8执行器核心?并且只有9.3 / 30GB RAM?我的印象是所有这些配置都应该自动处理,但即使是我手动调整的尝试都没有让我到处都是。
例如,我尝试使用以下命令启动shell:
spark-shell --conf spark.executor.cores=8 --conf spark.executor.memory=24g
但随后
失败了java.lang.IllegalArgumentException: Required executor memory (24576+930 MB) is above the max threshold (22528 MB) of this cluster! Please increase the value of 'yarn.scheduler.maximum-allocation-mb'.
我尝试更改/etc/hadoop/conf/yarn-site.xml
中的关联值,但没有效果。即使我尝试不同的群集设置(例如使用具有60+ GB RAM的执行程序),我也会遇到同样的问题。出于某种原因,最大阈值保持在22528MB。
我在这里做错了什么,或者这是Google自动配置的问题?
答案 0 :(得分:8)
群集中的默认内存配置存在一些已知问题,其中主机类型与工作机类型不同,但在您的情况下似乎不是主要问题。
当您看到以下内容时:
spark.executor.cores 4
spark.executor.memory 9310m
这实际上意味着每个工作节点将运行2个执行程序,每个执行程序将使用4个核心,这样所有8个核心确实在每个工作程序上用完。这样,如果我们将AppMaster提供给一台机器的一半,AppMaster就可以成功地打包到执行程序旁边。
给NodeManager的内存量需要为NodeManager守护进程本身和misc留下一些开销。其他守护进程服务,如DataNode,所以~80%留给NodeManagers。此外,分配必须是最小YARN分配的倍数,因此在铺设到最近的分配倍数之后,22528MB来自n1-standard-8。
如果您添加具有60 GB以上RAM的工作线程,那么只要您使用相同内存大小的主节点,那么您应看到更高的最大阈值数。
无论哪种方式,如果你看到OOM问题,那么重要的是内存每个执行程序,而不是每个任务的内存。如果你在spark.executor.cores
的同时增加spark.executor.memory
,那么每个任务的内存实际上并没有增加,所以你真的不会给你更多的空间那种情况下的应用逻辑; Spark将使用spark.executor.cores
来确定在同一内存空间中运行的并发任务数。
要实际为每个任务获得更多内存,您应该尝试:
如果您执行上述(2)或(3),那么与尝试占用所有内核的默认配置相比,您确实会让内核空闲,但这确实是获得更多内核的唯一途径除了转到{{1}}实例之外,每个任务的内存。