上次写了一篇关于配置参数是如何影响mapreduce的实际调度的参考:
- opts(yarn.app.mapreduce.am.command-opts、mapreduce.map.java.opts、mapreduce.reduce.java.opts)是实际运行程序是内存参数。
- memory(yarn.app.mapreduce.am.resource.mb、mapreduce.map.memory.mb、mapreduce.reduce.memory.mb)是用于ResourceManager计算集群资源使用和调度。
了解参数区别,就没有再深究task内存的问题了。
新问题-内存分配
这次又遇到内存问题:spark使用yarn-client的方式运行时,spark有memoryOverhead的设置,但是加了额外的内存后,再经过集群调度内存浪费严重,对于本来就小内存的集群来说完全无法接受。
- am默认是512加上384 overhead,也就是896m。但是调度后am分配内存资源为1024。
- executor默认是1024加上384,等于1408M。单调度后executor分配内存资源为2048。
从appmaster的日志可以看出来请求的内存大小是1408:
一个executor就浪费了500M,本来可以跑4个executor的但现在只能执行3个!
关于内存参数的具体含义查看官网: spark-on-yarn 和 yarn-default.xml
参数 | 值 | ||
---|---|---|---|
spark.yarn.am.memory | 512m | ||
spark.driver.memory | 1g | ||
spark.yarn.executor.memoryOverhead | executorMemory * 0.10, with minimum of 384 | ||
spark.yarn.driver.memoryOverhead | driverMemory * 0.10, with minimum of 384 | ||
spark.yarn.am.memoryOverhead | AM memory * 0.10, with minimum of 384 | ||
yarn.nodemanager.resource.memory-mb | 8192 | ||
yarn.scheduler.minimum-allocation-mb | 1024 | ||
yarn.scheduler.maximum-allocation-mb | 8192 |
分配的内存看着像是 最小分配内存 的整数倍。把 yarn.scheduler.minimum-allocation-mb
修改为512,重启yarn再运行,executor的分配的内存果真减少到1536(512*3)。
同时 http://blog.javachen.com/2015/06/09/memory-in-spark-on-yarn.html 这篇文章也讲 在YARN中,Container申请的内存大小必须为yarn.scheduler.minimum-allocation-mb的整数倍 。我们不去猜,调试下调度代码,看看究竟是什么情况。
1 2 3 4 5 6 7 8 9 |
|
本地eclipse在 CapacityScheduler#allocate
打断点,然后跑任务:
1 2 |
|
AppMaster内存分配:
Executor内存分配:
request进到allocate后,最终调用 DefaultResourceCalculator.normalize
重新计算了一遍请求需要的资源,把内存调整了。默认的DefaultResourceCalculator可以通过 capacity-scheduler.xml 的 yarn.scheduler.capacity.resource-calculator
来修改。
具体代码调度过程如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
|
小结
今天又重新认识一个yarn参数 yarn.scheduler.minimum-allocation-mb
,不仅仅是最小分配的内存,同时分配的资源也是minimum-allocation-mb的整数倍,还告诉我们 yarn.nodemanager.resource.memory-mb
也最好是minimum-allocation-mb的整数倍。
间接的学习了新的参数,可以通过 yarn.scheduler.capacity.resource-calculator
参数 来修改 CapacityScheduler 调度器的资源计算类。
–END