Как определить concurrency (потоки) при использовании shoryuken для фоновых заданий?

В моем приложении Ruby on Rails я использую shoryouken для фоновой обработки. У меня много запросов в очереди (6-7) в моем приложении. Одна из очередей имеет 2000-3000 заданий, и работнику требуется около 3 часов для обработки этих 2-3k заданий со значением по умолчанию concurrency из 25. Таким образом, исходя из каких факторов мы можем решить увеличить concurrency (который количество потоков для обработки заданий). Пожалуйста, сделайте комментарий, если что-то неясно в вопросе.

Ответ 1

Concurrency по умолчанию 25, но его можно изменить, изменив shoryuken.yml (см. ниже) или добавив аргумент concurrency следующим образом: shoryuken -c {desiredCount}

concurrency: 25  # Update with your desired value.
delay: 25        # The delay in seconds to pause a queue when it empty. Default 0
queues:
  - [high_priority, 6]
  - [default, 2]
  - [low_priority, 1]

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

Если узкое место существует вместо вашего БД или другого ресурса, вам необходимо соответствующим образом настроить его. (Вероятно, не так, но для тщательности)

EDIT: оптимизация производительности

В ответ на ваш вопрос об оптимизации подсчета потоков самым быстрым/лучшим способом определения оптимального значения concurrency является изменение concurrency и измерение пропускной способности реального мира. Существуют и другие подходы, но золотое правило для исполнения всегда измеряется в живой производственной среде. Синтетические тесты полезны только в той мере, в какой они отражают производительность в реальном времени. (См. Также: преждевременная оптимизация).

Это случай, когда вы легко можете одолеть вещи с чрезмерным значением (опять же, переосмысление вещей - это постоянная проблема в развитии). Просто измерьте с помощью соответствующих показателей (загрузка ЦП, использование памяти, количество заданий, выполненных за минуту), и измените количество потоков, пока вы не увеличите пропускную способность или не столкнетесь с узким местом.

Если ваши задачи связаны с ЦП, вы увидите, что максимальная загрузка вашего процессора. Если ваши задачи связаны с вводом-выводом, вы увидите, что через некоторое время увеличение количества параллельных потоков не приведет к увеличению пропускной способности, даже несмотря на то, что загрузка вашего процессора не повышается.

Узкое место ввода-вывода может случиться, когда любой из ресурсов, которые вы читаете/пишете, не в состоянии выполнить ваши требования к процессору. Это включает в себя системные ресурсы (память, дисковое пространство), производительность вашей базы данных (использование ЦП БД, ограничения чтения/записи), а также другие API-интерфейсы, с которыми вы подключаетесь. Емкость сети также является теоретическим узким местом, но если бы вы были достаточно большими, чтобы нанять кого-то с опытом работы в этой области. Поскольку существует так много разных способов, чтобы это произошло, единственный реальный способ понять, каковы узкие места, чтобы ваш мониторинг был на месте.

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

EDIT 2: Concurrency, задержка и пропускная способность

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

(Технически говоря, ваш параметр concurrency - ваше текущее ограничение)

Ответ 2

Три основных фактора:

  • Число ядер
  • Тип задания - привязка ввода/вывода или процессора
  • Есть ли другое приложение или процесс, выполняющийся на сервере

В идеале для задачи с привязкой к cpu следует сохранить число потоков в число ядер cpu.

Для задачи с привязкой к вводу/выводу она требует бенчмаркинга и вычисления времени ожидания ввода-вывода, а затем вы можете выбрать оптимальное значение. Для приблизительной оценки, если у вас есть 4 ядра, чем для задачи с привязкой к вводу/выводу, вы должны поддерживать максимум 8 потоков.

Если у вас есть приложение rails, работающее на нем, вам нужно уменьшить количество ядер.

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

Refer: http://baddotrobot.com/blog/2013/06/01/optimum-number-of-threads/