2017-03-06 604 views

回答

2

“虚拟核心”仅仅是实际核心的抽象。这种抽象或“谎言”(我喜欢称之为)允许YARN(和其他人)根据可用性动态旋转线程(并行处理)。举例来说,在一个“弹性”群集上运行地图缩减,处理限制仅限于您的钱包......云宝贝...。云。

你可以阅读更多here

+0

Thanks @ archae0pteryx。 – Tom

0

这里是文档状态(重点煤矿)

节点的容量应等于其 数量的物理内核的虚拟核心配置。应该请求一个容器,它可以饱和的内核数量为 预计一次可运行

除非CPU内核超线程它一次可以实际看到2个核心的一个物理核心只能运行一个线程(在超线程OS的情况下,可以运行两个线程 - 当然这是一个有点作弊和无效 - 与实际物理核心一样高效)。从本质上来说,最终用户意味着一个核心可以运行单线程,所以如果我想要使用java线程进行并行处理,理论上是这样,那么相当好的近似就是线程数等于核心数。因此,如果你的容器进程(这是一个JVM) 将需要2个线程,那么最好将它映射到2个vcore - 最后一行意味着什么。而且,核心的总容量应该等于物理核心的数量。

最重要的是要记住的仍然是它实际上是将调度线程在不同的内核中执行,因为它发生在任何其他应用程序和 纱线本身有控制它除了操作系统事实上,为每个容器分配多少个线程的最佳近似值是什么。这就是为什么重要的是要考虑在OS上运行的其他应用程序,内核等使用的CPU周期,因为所有内核都将永远不可用于YARN应用程序。

编辑:进一步研究

纱不影响CPU的硬限制,而是通过代码去,我可以看到它是如何试图影响CPU调度或CPU速度。技术上,Yarn可以启动不同的容器进程 - java,python,自定义shell命令等。在Yarn中启动容器的责任属于Node管理器的ContainerExecutor组件,我可以看到用于启动容器等的代码以及一些提示(取决于在平台上)。例如,在DefaultContainerExecutor(它扩展了ContainerExecutor)的情况下 - 对于windows,它使用“-c”参数进行cpu限制,并在linux上使用进程的好处来影响它。还有另一个实现LinuxContainerExecutor(或更好的CgroupsLCEResourcesHandler,因为前者不会强制使用cgroups),它尝试使用Linux cgroups来限制该节点上的Yarn CPU资源。更多细节可以参见here

ContainerExecutor { 
....... 
....... 

protected String[] getRunCommand(String command, String groupId, 
     String userName, Path pidFile, Configuration conf, Resource resource) { 
    boolean containerSchedPriorityIsSet = false; 
    int containerSchedPriorityAdjustment = 
     YarnConfiguration.DEFAULT_NM_CONTAINER_EXECUTOR_SCHED_PRIORITY; 

    if (conf.get(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY) != 
     null) { 
     containerSchedPriorityIsSet = true; 
     containerSchedPriorityAdjustment = conf 
      .getInt(YarnConfiguration.NM_CONTAINER_EXECUTOR_SCHED_PRIORITY, 
      YarnConfiguration.DEFAULT_NM_CONTAINER_EXECUTOR_SCHED_PRIORITY); 
    } 

    if (Shell.WINDOWS) { 
     int cpuRate = -1; 
     int memory = -1; 
     if (resource != null) { 
     if (conf 
      .getBoolean(
       YarnConfiguration.NM_WINDOWS_CONTAINER_MEMORY_LIMIT_ENABLED, 
       YarnConfiguration.DEFAULT_NM_WINDOWS_CONTAINER_MEMORY_LIMIT_ENABLED)) { 
      memory = resource.getMemory(); 
     } 

     if (conf.getBoolean(
      YarnConfiguration.NM_WINDOWS_CONTAINER_CPU_LIMIT_ENABLED, 
      YarnConfiguration.DEFAULT_NM_WINDOWS_CONTAINER_CPU_LIMIT_ENABLED)) { 
      int containerVCores = resource.getVirtualCores(); 
      int nodeVCores = conf.getInt(YarnConfiguration.NM_VCORES, 
       YarnConfiguration.DEFAULT_NM_VCORES); 
      // cap overall usage to the number of cores allocated to YARN 
      int nodeCpuPercentage = Math 
       .min(
        conf.getInt(
         YarnConfiguration.NM_RESOURCE_PERCENTAGE_PHYSICAL_CPU_LIMIT, 
         YarnConfiguration.DEFAULT_NM_RESOURCE_PERCENTAGE_PHYSICAL_CPU_LIMIT), 
        100); 
      nodeCpuPercentage = Math.max(0, nodeCpuPercentage); 
      if (nodeCpuPercentage == 0) { 
      String message = "Illegal value for " 
       + YarnConfiguration.NM_RESOURCE_PERCENTAGE_PHYSICAL_CPU_LIMIT 
       + ". Value cannot be less than or equal to 0."; 
      throw new IllegalArgumentException(message); 
      } 
      float yarnVCores = (nodeCpuPercentage * nodeVCores)/100.0f; 
      // CPU should be set to a percentage * 100, e.g. 20% cpu rate limit 
      // should be set as 20 * 100. The following setting is equal to: 
      // 100 * (100 * (vcores/Total # of cores allocated to YARN)) 
      cpuRate = Math.min(10000, 
       (int) ((containerVCores * 10000)/yarnVCores)); 
     } 
     } 
     return new String[] { Shell.WINUTILS, "task", "create", "-m", 
      String.valueOf(memory), "-c", String.valueOf(cpuRate), groupId, 
      "cmd /c " + command }; 
    } else { 
     List<String> retCommand = new ArrayList<String>(); 
     if (containerSchedPriorityIsSet) { 
     retCommand.addAll(Arrays.asList("nice", "-n", 
      Integer.toString(containerSchedPriorityAdjustment))); 
     } 
     retCommand.addAll(Arrays.asList("bash", command)); 
     return retCommand.toArray(new String[retCommand.size()]); 
    } 

    } 
     } 

对于windows(它利用winutils。exe),它使用cpu速率 对于Linux,它使用niceness作为参数来控制CPU优先级