Runtime.getRuntime (). AvailableProcessors () возвращает 1, хотя в ECS AWS доступно много ядер. - PullRequest
3 голосов
/ 09 апреля 2019

Я запускаю задачу через Docker в AWS ECS. Задача выполняет некоторые вычисления с привязкой к процессору, которые я хотел бы выполнить параллельно. Я запускаю пул потоков с числом потоков, указанным в Runtime.getRuntime().availableProcessors(), которое отлично работает локально на моем ПК. По какой-то причине в AWS ECS это всегда возвращает 1, даже если доступно несколько ядер. Поэтому мои вычисления выполняются последовательно и не используют несколько ядер.

Например, сейчас у меня есть задача, работающая на экземпляре "t3.medium", который должен иметь 2 ядра в соответствии с документами .

Когда я выполняю следующий код:

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

Тогда в журнале отображается следующее:

Java reports 1 cores

Я не указываю параметр cpu в определении задачи ECS. Я вижу, что в списке задач в консоли управления ECS есть столбец для «CPU», который для моей задачи читает 0. Я также заметил, что в списке экземпляров (= виртуальных машин) он указывает «доступный процессор» как 2048, что, вероятно, связано с тем фактом, что виртуальная машина имеет 2 ядра.

Я бы хотел, чтобы моя программа на Java видела все ядра, которые может предложить виртуальная машина. (Как обычно бывает, когда Java-программа выполняется на компьютере без Docker).

Как мне это сделать?

1 Ответ

0 голосов
/ 10 апреля 2019

Спасибо @stdunbar в комментариях за указание на правильное направление.

РЕДАКТИРОВАТЬ: Спасибо @Imran в комментариях.Если вы запустите много потоков, они будут обязательно запланированы на несколько ядер.Этот ответ только о том, чтобы Runtime.getRuntime().availableProcessors() вернул правильное значение.Многие «пулы потоков» запускают столько потоков, сколько возвращает этот метод: он должен возвращать количество доступных ядер.

Кажется, есть два основных решения, ни одно из которых не является идеальным:

  • Установите параметр cpu в определении задачи.Например, если у вас есть 2 ядра и вы хотите использовать их оба, вы должны установить "cpu":2048 в определении задачи.Это не очень удобно по двум причинам:

    • Если вы выбираете более крупный экземпляр, вы должны обязательно обновить этот параметр.

    • Если вы хотите, чтобы одновременно выполнялись две задачи, каждая из которых может периодически использовать все ядра для краткосрочных операций, AWS не будет планировать две задачи в двухъядерной системе с "cpu":2048.В нем говорится, что виртуальная машина «полна» с точки зрения процессора.Это идет вразрез с философией разделения времени (Unix и т. Д.) Для каждой задачи, выполняющей то, что ей нужно (например, представьте себе на настольном ПК, если вы запускаете Word и Excel на двухъядерном компьютере, а Windows не позволяет запуститьлюбые другие задачи на том основании, что Word может потребовать все одно ядро, а Excel может сделать тоже самое, поэтому если другой программе может понадобиться все ядро ​​вв то же время не хватит ядер.)

  • Используйте опцию -XX:ActiveProcessorCount=xx JVM в JDK 10 и далее, как описано здесь .Это не удобно, потому что:

    • Как указано выше, вы должны изменить значение, если измените тип экземпляра.

Я написалболее длинное сообщение в блоге, описывающее мои выводы здесь: https://www.databasesandlife.com/java-docker-aws-ecs-multicore/

...