Yarn正在使用虚拟核心的概念来管理CPU资源。我想问一下使用虚拟核心有什么好处,YARN使用vcore有什么理由吗?
答案 0 :(得分:3)
"虚拟内核"仅仅是实际核心的抽象。这种抽象或"谎言" (因为我喜欢称它),允许YARN(和其他人)根据可用性动态地旋转线程(并行进程)。例如,在"弹性"上运行地图缩小。只有你的钱包限制加工限制的集群......云宝贝......云。
您可以阅读更多here
答案 1 :(得分:2)
以下是文档说明(强调我的)
应该使用等于其的虚拟核心配置节点的容量 物理核心数量。应该要求一个容器 它可以饱和的核心数,即它的平均线程数 希望一次可以运行。
除非CPU内核是超线程的,否则它一次只能运行一个线程(如果超线程操作系统实际上看到一个物理内核有2个内核,并且可以运行两个线程 - 当然这有点作弊而且没有 - 就像拥有实际的物理核心一样高效)。基本上对最终用户来说意味着核心可以运行单个线程,所以理论上如果我想要使用java线程进行并行,那么一个相当不错的近似是线程数等于核心数。所以如果你的容器进程(这是一个JVM) 需要2个线程然后最好将它映射到2个vcore - 这是最后一行的含义。并且作为节点的总容量,vcore应该等于物理核心的数量。
最重要的是要记住,它实际上是操作系统,它将调度线程在不同的核心中执行,就像在任何其他应用程序中发生的那样 YARN本身不对它有控制权,除了为每个容器分配多少线程的最佳可能近似值。这就是为什么考虑运行在OS上的其他应用程序,内核使用的CPU周期等很重要的原因,因为YARN应用程序始终无法使用所有内核。
编辑:进一步研究
Yarn不影响CPU的硬限制但是通过代码我可以看到它如何影响CPU调度或CPU速率。从技术上讲,Yarn可以启动不同的容器进程 - java,python,自定义shell命令等。在Yarn中启动容器的责任属于Node Manager的ContainerExecutor组件,我可以看到启动容器等的代码,以及一些提示(取决于在平台上)。例如,在DefaultContainerExecutor
(扩展ContainerExecutor)的情况下 - 对于Windows,它使用“-c”参数进行cpu限制,而在linux上它使用进程良好来影响它。还有另一个实现LinuxContainerExecutor
(或者更好的是CgroupsLCEResourcesHandler
,因为前者不强制使用cgroup),它试图使用Linux cgroup来限制该节点上的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优先级的参数