我正在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。我还注意到,在实例(= VM)列表中,它将“CPU可用”列为2048,这大概与VM具有2个核心这一事实有关。我希望我的Java程序能够看到VM必须提供的所有内核。 (当Java程序在没有Docker的计算机上运行时,通常会发生这种情况)。
我该怎么做呢?
最佳答案
感谢@stdunbar在评论中为我指明了正确的方向。
编辑:感谢@Imran在评论中。如果您启动大量线程,则绝对会将它们调度到多个内核。这个答案只是关于让Runtime.getRuntime().availableProcessors()
返回正确的值。许多“线程池”启动与该方法返回的线程一样多的线程:它应返回可用核的数量。
似乎有两个主要解决方案,但都不是理想的:
cpu
参数。例如,如果您有2个核心,并且要同时使用它们,则必须在任务的定义中设置"cpu":2048
。这不是很方便,原因有两个:"cpu":2048
的2核系统上调度两个任务。从CPU的角度来看,VM表示“已满”。这违背了分时执行(Unix等)原则的每个任务都按需完成的任务(例如,想象一下在台式机上,如果您在双核计算机上运行Word和Excel,而Windows不允许您启动其他任何任务,因为Word可能需要一个核心,而Excel可能也需要,所以如果另一个程序可能同时需要所有核心,则将没有足够的核心。)-XX:ActiveProcessorCount=xx
JVM选项。这不方便,因为:我在这里写了一篇更长的博客文章,描述了我的发现:https://www.databasesandlife.com/java-docker-aws-ecs-multicore/
关于java - 即使ECS AWS上有许多可用内核,Runtime.getRuntime()。availableProcessors()仍返回1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55596774/