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

时间:2015-10-13 09:55:50

标签: hadoop mapreduce 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个空间提供了空间每个奴隶上的容器。这正是我工作中发生的事情,所以到目前为止没问题。

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

然后我尝试将mapreduce.map.memory.mbmapreduce.reduce.memory.mb从512增加到768.这为2个容器留出了空间(2048/768 = 2)。

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

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

nodemanager UI screenshot

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

所以要打破"它如何运作"提问多个问题:

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

1 个答案:

答案 0 :(得分:11)

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

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

  1. DefaultResourceCalculator :考虑到只有用于进行资源计算的内存(即用于计算容器数量)
  2. DominantResourceCalculator :考虑资源计算的内存和CPU
  3. 默认情况下,CapacityScheduler使用 DefaultResourceCalculator 。如果您想使用 DominantResourceCalculator ,则需要在“ capacity-scheduler.xml ”文件中设置以下属性:

      <property>
        <name>yarn.scheduler.capacity.resource-calculator</name>
        <value>org.apache.hadoop.yarn.util.resource.DominantResourceCalculator</value>
      </property>
    

    现在,回答你的问题:

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

    2. 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):

      int normalizedMemory = Math.min(roundUp(
      Math.max(r.getMemory(), minimumResource.getMemory()),
      stepFactor.getMemory()),maximumResource.getMemory());
      
    3. 其中:

      r =请求的内存

      逻辑如下:

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

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

      Roundup does : ((768 + (512 -1)) / 512) * 512 
      

      ℃。 min(roundup(512,stepFactor),maximumresource)= min(1279,1024)= 1024

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

      为了简单起见,你可以说综述,以512 MB(这是最小资源)的步长增加需求

      1. 由于Mapper是一个java进程, mapreduce.map.java.opts 用于指定映射器的堆大小。
      2. 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?

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

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

            int normalizedCores = Math.min(roundUp  
          `   Math.max(r.getVirtualCores(), minimumResource.getVirtualCores()), 
              stepFactor.getVirtualCores()), maximumResource.getVirtualCores());