MapReduce2 中如何基于 vcores 和内存创建容器?

How are containers created based on vcores and memory in MapReduce2?

我有一个由 1 个主节点(namenode、secondarynamenode、resourcemanager)和 2 个从节点(datanode、nodemanager)组成的小型集群。

我已经在大师的yarn-site.xml中设置了:

我已经在yarn-site.xml中设置了slaves:

然后在master里面,我在mapred-site.xml里面设置了:

所以据我了解,当 运行 一个作业时,mapreduce ApplicationMaster 将尝试在两个从属设备上创建尽可能多的 512 Mb 和 1 个 vCore 容器,每个从属设备只有 2048 Mb 和 4 个 vCores 可用,它为每个从站上的 4 个容器提供 space。这正是我工作中发生的情况,所以到目前为止没有问题。

但是,当我将 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) 留下了 space。

映射器和缩减器的 vCore 设置为 1 或 2 无关紧要,这始终会为每个从属设备生成 2 个 768mb 容器和 4 个 512mb 容器。那么 vCore 有什么用? ApplicationMaster 似乎并不关心。

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

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

所以要将 "how does it work" 问题分解成多个问题:

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

我会回答这个问题,假设使用的调度程序是 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>

现在,回答您的问题:

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

  2. mapreduce.map.memory.mb 不是抽象值。在计算资源时将其考虑在内。

    DominantResourceCalculator class 有一个 normalize() 函数,它使用 minimumResouce 规范化资源请求(由配置决定 yarn.scheduler.minimum-allocation-mb), maximumresource (由config yarn.scheduler.maximum-allocation-mb决定) 和一个step factor (由config 决定) yarn.scheduler.minimum-分配-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 of(requested resource and minimum resource) = max(768, 512) = 768

b。 roundup(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(这是最小资源)的步长增加需求

  1. 因为 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?

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

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

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