尽管ECS AWS上有许多可用核心,Runtime.getRuntime()。availableProcessors()返回1

问题描述 投票:2回答:1

我在AWS的ECS上通过Docker运行任务。该任务执行一些CPU绑定的计算,我想并行运行。我启动一个线程池,其中包含Runtime.getRuntime().availableProcessors()中指定的线程数,这在我的PC上本地工作正常。出于某种原因,在AWS ECS上,即使有多个可用核心,也始终返回1。因此,我的计算连续运行,并且不使用多核。

例如,现在,我有一个在“t3.medium”实例上运行的任务,根据docs应该有2个核心。

当我执行以下代码时:

System.out.println("Java reports " + 
    Runtime.getRuntime().availableProcessors() + " cores");

然后在日志中显示以下内容:

Java reports 1 cores

我没有在ECS的任务定义中指定cpu参数。我看到在ECS管理控制台的任务列表中,它有一个“CPU”列,它为我的任务读取0。我还注意到在实例列表(= VMs)中它将“CPU available”列为2048,这可能与VM有2个核心的事实有关。

我希望我的Java程序能够看到VM必须提供的所有核心。 (通常情况下,Java程序在没有Docker的计算机上运行)。

我该怎么做呢?

java docker amazon-ecs
1个回答
0
投票

感谢@stdunbar在评论中指出我正确的方向。

编辑:感谢@Imran的评论。如果你启动了很多线程,它们绝对会被安排到多个核心。这个答案只是让Runtime.getRuntime().availableProcessors()返回正确的价值。许多“线程池”启动的方法与该方法返回的线程数一样多:它应该返回可用的核心数。

似乎有两个主要解决方案,两者都不理想:

  • 在任务定义中设置cpu参数。例如,如果您有2个核心并且想要使用它们,则必须在任务的定义中设置"cpu":2048。由于两个原因,这不是很方便: 如果选择更大的实例,则必须确保更新此参数。 如果您希望同时运行两个任务,这两个任务都可以偶尔使用所有核心进行短期活动,AWS将不会在使用"cpu":2048的双核系统上安排两个任务。它表示从CPU的角度来看,VM是“完整的”。这违背了分时度假(Unix等)的理念,即每个任务都需要它(例如,想象一下台式PC,如果你在双核计算机上运行Word和Excel,Windows就不允许你开始任何其他任务,理由是Word可能需要所有的一个核心,而Excel可能也会这样做,所以如果另一个程序可能同时需要所有核心,那么就没有足够的核心。)
  • 使用JDK 10中的-XX:ActiveProcessorCount=xx JVM选项,如here所述。这不方便,因为: 如上所述,如果更改实例类型,则必须更改该值。

我在这里写了一篇更长篇博客文章描述我的发现:https://www.databasesandlife.com/java-docker-aws-ecs-multicore/

© www.soinside.com 2019 - 2024. All rights reserved.