运行时.getRuntime().可用处理器() 返回 1,即使 ECS AWS 上有许多内核可用

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

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

当我执行以下代码时:

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

然后,日志上将显示以下内容:

Java reports 1 cores

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

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

我该怎么做?


潇湘沐
浏览 115回答 1
1回答

拉丁的传说

如果您启动大量线程,它们绝对会被调度到多个内核。这个答案只是关于返回正确的值。许多“线程池”启动的线程数与该方法返回的线程数一样多:它应该返回可用的内核数。Runtime.getRuntime().availableProcessors()似乎有两个主要的解决方案,两者都不是理想的:在任务定义中设置参数。例如,如果您有 2 个内核,并且想要同时使用它们,则必须在任务的定义中进行设置。这不是很方便,原因有两个:cpu"cpu":2048如果选择更大的实例,则必须确保更新此参数。如果您希望同时运行两个任务,这两个任务都可以偶尔使用所有核心进行短期活动,AWS 不会在具有 的 2 核系统上安排两个任务。它说从CPU的角度来看,VM是“满”的。这违背了分时(Unix等)的理念,即每个任务都采用它需要的东西(例如,想象一下,在台式PC上,如果你在双核计算机上运行Word和Excel,而Windows不允许你启动任何其他任务,理由是Word可能需要所有一个核心,而Excel也可能这样做, 因此,如果另一个程序可能同时需要所有内核,则没有足够的内核。"cpu":2048在 JDK 10 及更高版本中使用 JVM 选项,如此处所述。这并不方便,因为:-XX:ActiveProcessorCount=xx如上所述,如果您更改实例类型,则必须更改该值。我写了一篇更长的博客文章,在这里描述了我的发现:https://www.databasesandlife.com/java-docker-aws-ecs-multicore/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java