2017-03-06 64 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優先級