昨天在yarn集群上跑代码遇到这个问题,现在发现spark代码写好是重要的一方面,spark submit参数设置也起着重要的作用
Container killed by YARN for exceeding memory limits,直白的意思就是超出内存限制了,查看yarn集群的设置,在yarn的配置表
yarn.scheduler.maximum-allocation-mb设置值6114,也就是说单个container申请的最大内存是这么多,但是执行任务的时候你的executer需要的内存超出这个值,那么就会被杀掉。
在google一遍之后,网上给出的答案是调节参数 spark.yarn.executor.memoryOverhead,这个参数就是给executer预留的内存,默认情况下是
// Below calculation uses executorMemory, not memoryOverhead math.max((MEMORY_OVERHEAD_FACTOR * executorMemory).toInt, MEMORY_OVERHEAD_MIN))
其中,MEMORY_OVERHEAD_FACTOR默认为0.1,executorMemory为设置的executor-memory, MEMORY_OVERHEAD_MIN默认为384m。参数MEMORY_OVERHEAD_FACTOR和MEMORY_OVERHEAD_MIN一般不能直接修改,是Spark代码中直接写死的。
executor-memory计算
计算公式:
<span class="hljs-attribute"> val executorMem </span>=<span class="hljs-string"> args.executorMemory + executorMemoryOverhead</span>
假设executor-为X(整数,单位为M),即 1) 如果没有设置spark.yarn.executor.memoryOverhead,
<span class="hljs-attribute">executorMem</span>=<span class="hljs-string"> X+max(X*0.1,384)</span>
2)如果设置了spark.yarn.executor.memoryOverhead(整数,单位是M)
executorMem=<span class="hljs-built_in">X</span> +spark<span class="hljs-preprocessor">.yarn</span><span class="hljs-preprocessor">.executor</span><span class="hljs-preprocessor">.memoryOverhead</span>
需要满足的条件:
executorMem< yarn<span class="hljs-preprocessor">.scheduler</span><span class="hljs-preprocessor">.maximum</span>-allocation-mb
说了这么一大堆,可能部分人的情况可以解决,但是博主的问题依然存在,这个时候请教了一下组内的同事,同事看了下我spark-submit提交的参数,让我修改了exectute-cores 和executer-number 以及executer-memmory ,driver-memory,调节了以后还是炸锅了。。。那么去看了一下代码,代码目前没有任何的持久化操作,shuffle操作以目前的数据量可以接受
解决的办法竟然是修改数据的分区数,打印了spark默认分配的分区数,尼玛就只有3个啊,我一狠心重新分配至50个,然后提交测试一下,然后默默的看着屏幕不算打印INFO信息,直至跑完。。。。。
不断学习,不断成长,感谢蒋大兄弟的帮助