首页 文章

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

提问于
浏览
10

我有一个由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) .

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上显示了此信息以用于映射器容器:

nodemanager UI screenshot

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 回答

  • 11

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

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

    • DefaultResourceCalculator :考虑到,只有用于进行资源计算的内存(即用于计算容器数)

    • 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>
    

    现在,回答你的问题:

    • 如果使用 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):

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

    哪里:

    r =请求的内存

    逻辑如下:

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

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

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

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

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

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

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

    其中 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?

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

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

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

相关问题