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()]);
}
}
}
2条答案
按热度按时间deikduxw1#
以下是文档说明的内容(我的重点)
节点的容量应配置为与物理核数相等的虚拟核。请求一个容器时,应该使用它可以饱和的内核数,即它期望一次可以运行的线程的平均数。
除非cpu内核是超线程的,否则它一次只能运行一个线程(在超线程操作系统的情况下,一个物理内核可以运行两个线程—当然这有点作弊,没有实际物理内核那么有效)。从本质上讲,它对最终用户的意义是,一个核心可以运行一个线程,所以理论上,如果我想使用java线程实现并行,那么一个相当好的近似值是线程数等于核心数。因此,如果容器进程(jvm)需要2个线程,那么最好将其Map到2vcore,这就是最后一行的意思。作为节点的总容量,vcore应该等于物理核的数量。
要记住的最重要的一点是,实际上是操作系统将线程调度到不同的核心中执行,就像在任何其他应用程序中一样,而yarn本身并没有对它的控制权,除了为每个容器分配多少线程的最佳近似值。这就是为什么考虑运行在操作系统上的其他应用程序、内核使用的cpu周期等是很重要的,因为所有的内核不会一直对应用程序可用。
编辑:进一步研究
yarn并不影响cpu的硬限制,但是通过代码我可以看到它是如何影响cpu调度或cpu速率的。从技术上讲,yarn可以启动不同的容器进程-java、python、自定义shell命令等。在yarn中启动容器的责任属于node manager的containerexecutor组件,我可以看到启动容器的代码等,以及一些提示(取决于平台)。例如,在
DefaultContainerExecutor
(它扩展了containerexecutor)-对于windows,它使用“-c”参数来限制cpu,而对于linux,它使用进程精确性来影响cpu。还有另一个实现LinuxContainerExecutor
(或者更好CgroupsLCEResourcesHandler
因为前者不强制使用cgroups),后者试图使用linux cgroups来限制该节点上的cpu资源。更多细节可以在这里找到。对于windows(它使用winutils.exe),它使用cpu速率;对于linux,它使用niceness作为参数来控制cpu优先级
agyaoht72#
“虚拟核心”只是实际核心的抽象。这种抽象或“lie”(我喜欢称之为lie),允许yarn(和其他)基于可用性动态地旋转线程(并行进程)。例如,在一个“弹性”集群上运行map reduce,其处理限制仅限于您的钱包。。。云宝宝。。。这个。云。
你可以在这里读更多