Создание потока Akka Dispatcher

Я работаю над моделью Akka Actor. У меня есть вариант использования, в котором будут активны более 1000 актеров, и мне нужно обработать этих актеров. Я думал об управлении количеством потоков с помощью конфигурации, определенной в application.conf.

Но нет. потока диспетчера, созданного в моем приложении, делает меня беспомощным в настройке конфигурации диспетчера. Каждый раз, когда я перезапускаю свое приложение, я вижу разное количество созданных потоков диспетчера (я проверял это через дамп потока каждый раз после запуска приложения).

Даже количество потоков не равно тому, которое я определил в parallelism-min. Из-за этого небольшого количества потоков мое приложение обрабатывается очень медленно. При проверке нет. ядра на моей машине с помощью приведенного ниже кода:

Runtime.getRuntime(). AvailableProcessors();

Он показывает 40. Но нет. количество созданных потоков диспетчера меньше 300, даже если я настроил параллелизм как 500.

Ниже приведен мой файл application.conf:

consumer-dispatcher {
  type = "Dispatcher"

  executor = "fork-join-executor"

  fork-join-executor {
    parallelism-min = 500
    parallelism-factor = 20.0
    parallelism-max = 1000
  }

  shutdown-timeout = 1s

  throughput = 1
}

Могу ли я узнать, на каком основании akka будет создавать внутренние потоки диспетчера и как я могу увеличить количество потоков диспетчера, чтобы увеличить параллельную обработку акторов?


person Hemnath    schedule 18.03.2020    source источник


Ответы (1)


X-Post от discuss.lightbend.com

Сначала позвольте мне ответить на вопрос прямо.

fork-join-executor будет поддерживаться пулом java.util.concurrent.forkJoinPool с параллелизмом, установленным на подразумеваемый параллелизм из конфигурации диспетчера. (коэффициент параллелизма * процессоры, но не больше max и не меньше min). Так что в вашем случае 800.

И хотя я не эксперт по реализации ForkJoinPool, в источнике Java-реализации ForkJoinPool говорится: «Все рабочие потоки создаются по запросу, инициируются отправкой задач, заменой уволенных рабочих и/или компенсацией за заблокированных рабочих. ” и у него есть такие методы, как getActiveThreads(), поэтому ясно, что ForkJoinPool не просто наивно создает гигантский пул рабочих.

Другими словами, то, что вы видите, ожидаемо: потоки будут создаваться только по мере необходимости. Если вам действительно нужен гигантский пул рабочих потоков, вы можете создать исполнителя пула потоков с фиксированным размером пула 800. Это даст вам реализацию, которую вы ищете.

Но прежде чем вы это сделаете, я думаю, вы полностью упускаете из виду актеров и Акку. Одна из причин, по которой людям нравятся акторы, заключается в том, что они намного легче, чем потоки, и могут дать вам гораздо больше параллелизма, чем потоки. (Также обратите внимание, что параллелизм != параллелизм, как указано в документации по концепциям.) Таким образом, попытка создать пул из 800 потоков для поддержки 1000 акторов очень расточительна. В введении к документам akka указано подчеркивает «Миллионы актеров можно эффективно запланировать на дюжину потоков».

Я не могу точно сказать вам, сколько потоков вам нужно, не зная вашего приложения (например, если у вас есть блокирующее поведение), но значения по умолчанию (которые дают вам коэффициент параллелизма 20), вероятно, вполне подходят. Сравните, чтобы быть уверенным, но я действительно не думаю, что у вас есть проблема со слишком небольшим количеством потоков. (Кажется, поведение ForkJoinPool, которое вы наблюдаете, подтверждает это.)

person David Ogren    schedule 21.03.2020