如何根据MapReduce2中的vcores和内存创建容器?

Nic*_*mak 10 hadoop mapreduce hadoop-yarn

我有一个由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个容器奴隶.这正是我工作中发生的事情,所以到目前为止没问题.

但是,当我将1 mapreduce.map.cpu.vcoresmapreduce.reduce.cpu.vcores1 递增时,理论上应该只有足够的vCore可用于为每个奴隶创建2个容器吗?但不,我每个奴隶仍有4个容器.

然后我试图增加mapreduce.map.memory.mbmapreduce.reduce.memory.mb从512到768.这留下空间2个容器(七百六十八分之二千零四十八= 2).

如果将vCore设置为1或2用于映射器和缩减器无关紧要,这将始终为每个从站生成2个容器,其中768mb和4个512mb容器.那么vCores是为了什么?ApplicationMaster似乎并不关心.

此外,当将内存设置为768并将vCores设置为2时,我在nodemanager UI上显示了此信息以用于映射器容器:

nodemanager UI截图

768 Mb已变为1024 TotalMemoryNeeded,并且2个vCores被忽略并显示为1 TotalVCoresNeeded.

因此,将"如何运作"问题分解为多个问题:

  1. 是否仅使用内存(并忽略vCores)来计算容器数量?
  2. mapreduce.map.memory.mb值是否只是用于计算容器数量的完全抽象值(这就是为什么它可以舍入到下一个2的幂)?或者它以某种方式代表真实的内存分配?
  3. 为什么我们指定一些-Xmx值mapreduce.map.java.opts?为什么纱线不使用from mapreduce.map.memory.mb来为容器分配内存?
  4. 什么是TotalVCoresNeeded,为什么它总是等于1?我试图改变mapreduce.map.cpu.vcores所有节点(主节点和从节点),但它永远不会改变.

Man*_*lur 12

我将回答这个问题,假设调度程序使用的是CapacityScheduler.

CapacityScheduler使用ResourceCalculator计算应用程序所需的资源.有两种类型的资源计算器:

  1. DefaultResourceCalculator:考虑到,只有用于进行资源计算的内存(即用于计算容器数)
  2. DominantResourceCalculator:考虑资源计算的内存和CPU

默认情况下,CapacityScheduler使用DefaultResourceCalculator.如果要使用DominantResourceCalculator,则需要在" capacity-scheduler.xml "文件中设置以下属性:

  <property>
    <name>yarn.scheduler.capacity.resource-calculator</name>
    <value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
  </property>
Run Code Online (Sandbox Code Playgroud)

现在,回答你的问题:

  1. 如果使用DominantResourceCalculator,则会考虑内存和VCores来计算容器数

  2. mapreduce.map.memory.mb不是抽象值.在计算资源时要考虑到这一点.

    DominantResourceCalculator类有一个归一化()函数,它归一化该资源请求,使用minimumResouce(由配置确定yarn.scheduler.minimum分配-MB,maximumresource)(由配置确定 yarn.scheduler.maximum分配-MB)和步长因子(由config yarn.scheduler.minimum-allocation-mb确定).

    规范化内存的代码如下所示(检查org.apache.hadoop.yarn.util.resource.DominantResourceCalculator.java):

    int normalizedMemory = Math.min(roundUp(
    Math.max(r.getMemory(), minimumResource.getMemory()),
    stepFactor.getMemory()),maximumResource.getMemory());
    
    Run Code Online (Sandbox Code Playgroud)

哪里:

r =请求的内存

逻辑如下:

一个.取最大值(请求的资源和最小资源)= max(768,512)= 768

湾 综述(768,StepFactor)= roundUp(768,512)== 1279(大约)

Roundup does : ((768 + (512 -1)) / 512) * 512 
Run Code Online (Sandbox Code Playgroud)

C.min(roundup(512,stepFactor),maximumresource)= min(1279,1024)= 1024

所以最后,分配的内存是1024 MB,这是你得到的.

为简单起见,您可以说汇总,以512 MB(这是最小资源)的步长增加需求

  1. 由于Mapper是一个java进程,因此mapreduce.map.java.opts用于指定映射器的堆大小.

其中作为mapreduce.map.memory.mb是由容器所使用的总存储器.

mapreduce.map.java.opts的值应小于mapreduce.map.memory.mb

这里的答案解释了:Apache Hadoop YARN中'mapreduce.map.memory.mb'和'mapred.map.child.java.opts'之间的关系是什么?

  1. 当您使用DominantResourceCalculator时,它使用normalize()函数来计算所需的vCore.

    代码是(类似于内存的规范化):

      int normalizedCores = Math.min(roundUp  
    `   Math.max(r.getVirtualCores(), minimumResource.getVirtualCores()), 
        stepFactor.getVirtualCores()), maximumResource.getVirtualCores());
    
    Run Code Online (Sandbox Code Playgroud)