我有一个由1个master(namenode,secondarynamenode,resourcemanager)和2个slave(datanode,nodemanager)组成的小集群 .
我已经设置了master的yarn-site.xml:
-
yarn.scheduler.minimum-allocation-mb
:512 -
yarn.scheduler.maximum-allocation-mb
:1024 -
yarn.scheduler.minimum-allocation-vcores
:1 -
yarn.scheduler.maximum-allocation-vcores
:2
我已经设置了奴隶的yarn-site.xml:
-
yarn.nodemanager.resource.memory-mb
:2048 -
yarn.nodemanager.resource.cpu-vcores
:4
然后在master中,我在mapred-site.xml中设置了:
-
mapreduce.map.memory.mb
:512 -
mapreduce.map.java.opts
:-Xmx500m -
mapreduce.map.cpu.vcores
:1 -
mapreduce.reduce.memory.mb
:512 -
mapreduce.reduce.java.opts
:-Xmx500m -
mapreduce.reduce.cpu.vcores
:1
所以我的理解是,在运行作业时,mapreduce ApplicationMaster将尝试在两个从站上创建512 Mb和1 vCore的容器,每个从站只有2048 Mb和4个vCore,每个容器可以容纳4个容器奴隶 . 这正是我工作中发生的事情,所以到目前为止没问题 .
但是,当我将 mapreduce.map.cpu.vcores
和 mapreduce.reduce.cpu.vcores
从1增加到2时,理论上应该只有足够的vCore可用于为每个奴隶创建2个容器吗?但不,我每个奴隶仍有4个容器 .
然后我尝试将 mapreduce.map.memory.mb
和 mapreduce.reduce.memory.mb
从512增加到768.这为2个容器留出了空间(2048/768 = 2) .
It doesn't matter if the vCores are set to 1 or 2 for mappers and reducers, this will always produce 2 containers per slave with 768mb and 4 containers with 512mb. So what are vCores for ? The ApplicationMaster doesn't seem to care.
此外,当将内存设置为768并将vCores设置为2时,我在nodemanager UI上显示了此信息以用于映射器容器:
768 Mb已变为1024 TotalMemoryNeeded,并且2个vCores被忽略并显示为1 TotalVCoresNeeded .
因此,将“如何运作”问题分解为多个问题:
-
是否仅使用内存(并忽略vCores)来计算容器数量?
-
mapreduce.map.memory.mb
值是否只是一个用于计算容器数量的完全抽象值(这就是为什么它可以向上舍入为2的下一个幂)?或者它以某种方式代表真实的内存分配? -
为什么我们在
mapreduce.map.java.opts
中指定一些-Xmx值?为什么纱线不使用mapreduce.map.memory.mb
中的值来为容器分配内存? -
什么是TotalVCoresNeeded,为什么总是等于1?我试图在所有节点(主站和从站)中更改
mapreduce.map.cpu.vcores
但它永远不会改变 .
1 回答
我将回答这个问题,假设调度程序使用的是 CapacityScheduler .
CapacityScheduler 使用 ResourceCalculator 来计算应用程序所需的资源 . 有两种类型的资源计算器:
DefaultResourceCalculator :考虑到,只有用于进行资源计算的内存(即用于计算容器数)
DominantResourceCalculator :考虑资源计算的内存和CPU
默认情况下,CapacityScheduler使用 DefaultResourceCalculator . 如果要使用 DominantResourceCalculator ,则需要在“ capacity-scheduler.xml ”文件中设置以下属性:
现在,回答你的问题:
如果使用 DominantResourceCalculator ,则会考虑内存和VCore来计算容器数量
mapreduce.map.memory.mb 不是抽象值 . 在计算资源时要考虑到这一点 .
DominantResourceCalculator 类有一个normalize()函数,它使用minimumResouce(由config yarn.scheduler.minimum-allocation-mb 确定),maximumresource(由config yarn.scheduler.maximum-allocation-mb 确定)和步长因子(由config yarn.scheduler.minimum-allocation-mb 确定)规范化资源请求 .
规范化内存的代码如下所示(检查org.apache.hadoop.yarn.util.resource.DominantResourceCalculator.java):
哪里:
r =请求的内存
逻辑如下:
一个 . 取最大值(请求的资源和最小资源)= max(768,512)= 768
湾综述(768,StepFactor)= roundUp(768,512)== 1279(大约)
C . min(roundup(512,stepFactor),maximumresource)= min(1279,1024)= 1024
所以最后,分配的内存是1024 MB,这是你得到的 .
为简单起见,您可以说汇总,以512 MB(这是最小资源)的步长增加需求
其中 mapreduce.map.memory.mb 是容器使用的总内存 .
mapreduce.map.java.opts 的值应小于 mapreduce.map.memory.mb
这里的答案解释了:What is the relation between 'mapreduce.map.memory.mb' and 'mapred.map.child.java.opts' in Apache Hadoop YARN?
代码是(类似于内存的规范化):