我一直在遇到一些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.
我在这里做错了什么,或者这是谷歌自动配置的问题?
群集中的默认内存配置存在一些已知问题,其中主机类型与工作机类型不同,但在您的情况下似乎不是主要问题.
当您看到以下内容时:
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
确定在同一内存空间中运行的并发任务数.
要实际为每个任务获得更多内存,您应该主要尝试:
使用n1-highmem-*机器类型
尝试减少 spark.executor.cores,同时保持spark.executor.memory相同
尝试增加spark.executor.memory,同时保留spark.executor.cores
如果您执行上面的(2)或(3),那么与尝试占用所有内核的默认配置相比,您确实会让内核空闲,但这实际上是除了转到highmem
实例之外每个任务获得更多内存的唯一方法.