2016-01-22 82 views
0

我的纱线容器内存不足: 此特定容器运行Apache-Spark驱动程序节点。纱线容器内存不足

我不明白的部分:我限制我的驱动程序的堆大小为512MB(您可以在下面的错误消息中看到这一点)。但纱容器抱怨内存大于1GB(另请参见下面的消息)。您可以验证该纱线是否正在启动Java,并使用Xmx512m运行。我的容器设置为1GB内存,增量为0.5GB。另外我的物理机器托管容器每个都有32GB。我SSH到了其中一个物理机器,并看到它有很多空闲内存...

另一个奇怪的事情是,java不抛出OutOfMemory异常。当我查看驱动程序日志时,我发现最终它从纱线中获得了SIGTERM,并很好地关闭。如果Yarn内部的java进程超过了512MB,那么在它尝试从纱线中分配1GB之前,是否应该在Java中获得OutOfMemory异常?

我也尝试使用1024m堆运行。那一次,容器崩溃,使用量为1.5GB。这发生了一致。很显然,容器有能力在1GB的限制之外再分配0.5GB的容量。 (相当逻辑,因为物理机有30GB的空闲内存)

除了java可以占用多余的512MB的YARN容器内部还有其他东西吗?

我在纱线上运行Apache Spark的CDH 5.4.1。集群上的Java版本也升级到Oracle Java8。我看到一些人声称在java8默认MaxPermSize参数已经改变,但我很难相信,这可能需要多达512MB ...

纱错误消息:

Diagnostics: Container [pid=23335,containerID=container_1453125563779_0160_02_000001] is running beyond physical memory limits. Current usage: 1.0 GB of 1 GB physical memory used; 2.6 GB of 2.1 GB virtual memory used. Killing container. 
Dump of the process-tree for container_1453125563779_0160_02_000001 : 
    |- PID PPID PGRPID SESSID CMD_NAME USER_MODE_TIME(MILLIS) SYSTEM_TIME(MILLIS) VMEM_USAGE(BYTES) RSSMEM_USAGE(PAGES) FULL_CMD_LINE 
    |- 23335 23333 23335 23335 (bash) 1 0 11767808 432 /bin/bash -c LD_LIBRARY_PATH=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native::/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native /usr/lib/jvm/java-8-oracle/bin/java -server -Xmx512m -Djava.io.tmpdir=/var/yarn/nm/usercache/hdfs/appcache/application_1453125563779_0160/container_1453125563779_0160_02_000001/tmp '-Dspark.eventLog.enabled=true' '-Dspark.executor.memory=512m' '-Dspark.executor.extraClassPath=/opt/cloudera/parcels/CDH/lib/hbase/lib/htrace-core-3.1.0-incubating.jar' '-Dspark.yarn.am.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native' '-Dspark.executor.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native' '-Dspark.shuffle.service.enabled=true' '-Dspark.yarn.jar=local:/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/spark/assembly/lib/spark-assembly-1.3.0-cdh5.4.1-hadoop2.6.0-cdh5.4.1.jar' '-Dspark.app.name=not_telling-1453479057517' '-Dspark.shuffle.service.port=7337' '-Dspark.driver.extraClassPath=/etc/hbase/conf:/opt/cloudera/parcels/CDH/lib/hbase/lib/htrace-core-3.1.0-incubating.jar' '-Dspark.serializer=org.apache.spark.serializer.KryoSerializer' '-Dspark.yarn.historyServer.address=http://XXXX-cdh-dev-cdh-node2:18088' '-Dspark.driver.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native' '-Dspark.eventLog.dir=hdfs://XXXX-cdh-dev-cdh-node1:8020/user/spark/applicationHistory' '-Dspark.master=yarn-cluster' -Dspark.yarn.app.container.log.dir=/var/log/hadoop-yarn/container/application_1453125563779_0160/container_1453125563779_0160_02_000001 org.apache.spark.deploy.yarn.ApplicationMaster --class 'not_telling' --jar file:/home/cloud-user/temp/not_telling.jar --arg '--conf' --arg 'spark.executor.extraClasspath=/opt/cloudera/parcels/CDH/jars/htrace-core-3.0.4.jar' --executor-memory 512m --executor-cores 4 --num-executors 10 1> /var/log/hadoop-yarn/container/application_1453125563779_0160/container_1453125563779_0160_02_000001/stdout 2> /var/log/hadoop-yarn/container/application_1453125563779_0160/container_1453125563779_0160_02_000001/stderr 
    |- 23338 23335 23335 23335 (java) 95290 10928 2786668544 261830 /usr/lib/jvm/java-8-oracle/bin/java -server -Xmx512m -Djava.io.tmpdir=/var/yarn/nm/usercache/hdfs/appcache/application_1453125563779_0160/container_1453125563779_0160_02_000001/tmp -Dspark.eventLog.enabled=true -Dspark.executor.memory=512m -Dspark.executor.extraClassPath=/opt/cloudera/parcels/CDH/lib/hbase/lib/htrace-core-3.1.0-incubating.jar -Dspark.yarn.am.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native -Dspark.executor.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native -Dspark.shuffle.service.enabled=true -Dspark.yarn.jar=local:/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/spark/assembly/lib/spark-assembly-1.3.0-cdh5.4.1-hadoop2.6.0-cdh5.4.1.jar -Dspark.app.name=not_tellin-1453479057517 -Dspark.shuffle.service.port=7337 -Dspark.driver.extraClassPath=/etc/hbase/conf:/opt/cloudera/parcels/CDH/lib/hbase/lib/htrace-core-3.1.0-incubating.jar -Dspark.serializer=org.apache.spark.serializer.KryoSerializer -Dspark.yarn.historyServer.address=http://XXXX-cdh-dev-cdh-node2:18088 -Dspark.driver.extraLibraryPath=/opt/cloudera/parcels/CDH-5.4.1-1.cdh5.4.1.p0.6/lib/hadoop/lib/native -Dspark.eventLog.dir=hdfs://XXXX-cdh-dev-cdh-node1:8020/user/spark/applicationHistory -Dspark.master=yarn-cluster -Dspark.yarn.app.container.log.dir=/var/log/hadoop-yarn/container/application_1453125563779_0160/container_1453125563779_0160_02_000001 org.apache.spark.deploy.yarn.ApplicationMaster --class not_telling --jar file:not_telling.jar --arg --conf --arg spark.executor.extraClasspath=/opt/cloudera/parcels/CDH/jars/htrace-core-3.0.4.jar --executor-memory 512m --executor-cores 4 --num-executors 10 

回答

0

退房this article,它有一个很好的描述。您可能需要注意他们在说什么“在计算执行程序的内存时,请注意最大(7%,384米)开销堆内存。”

编辑(通过Eshalev):我正在接受这个答案,并详细说明了发现的内容。 Java8使用不同的内存方案。具体的CompressedClasses在“Metaspace”中保留1024MB。这比以前版本的java在“perm-gen”内存中分配的要大得多。你可以使用“jmap -heap [pid]”来检查它。我们目前通过超出我们的堆需求超过1024MB而使应用程序崩溃。这是浪费,但它使应用程序不会崩溃。

0

有时候问题在于你的RDD没有被均分。您也可以尝试增加分区(通过执行合并或重新分区,您也可以使用partitionBy)对每个/某个转换进行分区。

+0

不应该这样造成一个OutOfMemoryException从Java内部的方法更早?我希望这会烧毁我所有的堆内存和崩溃。 (我limitted Java堆与XMX ...) – eshalev

+0

特殊照顾的权利。但也许你可以尝试让你的遗嘱执行人均匀分布 – minyo

2

您的应用程序因虚拟内存使用而被终止(请注意,使用2.1GB消息中的2.6)。

几个选项,可以帮助:纱线-site.xml中

  1. 禁用虚拟内存检查,通过改变 “yarn.nodemanager.vmem检查启用” 为false。这是相当频繁地完成的,这通常是我坦白的。
  2. 增加“spark.yarn.executor.memoryOverhead”和“spark.yarn.driver.memoryOverhead”,直到您的作业停止死亡。

这样做的原因是因为YARN限制了您的进程允许使用的堆内存量。如果您的应用程序有大量的可执行代码(java 7或更早版本中的大型perm gen),您将很快达到此限制。如果您使用堆叠内存非常频繁使用的pyspark,您也很有可能击中它。

+0

呀,还是可以理解为什么Hadoop是保持在默认情况下启用此的vmem检查。在Linux(或任何其他操作系统)上几乎不可能使用jvm进程可靠地跟踪vmem。如果你需要在纱线上运行任何东西,首先要禁用vmem检查。 –

1

,除非你要处理的数据非常几行,你会不远处,每执行1GB内存去。

来计算,你可以使用正确的ressources最好的办法是这样的: 占用CPU和内存的NB你有1节点上,留下1为系统HDFS 4个CPU核心(1个芯4 4core节点的情况下,核心,如果你有32个核心节点) 除以2至5(至少2个具有多任务与广播数据和不要超过5,你将面临不良HDFS IO带宽),你会得到您可以在一个节点上拥有的执行者数量。 现在采取的RAM的容量此节点,寻找最大taht纱允许你在一个节点的所有集装箱(这应该是接近26 GB您的情况),并通过计算之前执行的数量除以它。 删除10%,你得到了一个执行者的金额或内存。

手动设定执行程序存储器中作为HDP或CDH可能强制其384MB至极的spark.yarn.executor.memoryOverhead到10%是最小值。

现在实例的数量,乘以节点执行人X号的号码,并移除1对驱动器(是的,你应该提高内存和CPU的数量驱动程序的方法相同)

所以例如我已经在AWS 3个节点R4.8xlarge每一个具有32 cpu和244GB存储器和让我有每20个执行人与4个CPU和26 GB存储器

spark.executor.memory=26g 
spark.yarn.executor.memoryOverhead=2600 
spark.driver.memory=26g 
spark.yarn.driver.memoryOverhead=2600 
spark.executor.cores=4 
spark.executor.instances=20 
spark.driver.cores=4 

之后,你可以根据需要调你的配置,例如你可能会减少执行器的数量,让它们拥有更多的内存。