Сколько воркеров можно запустить на одну задачу?

«Сколько воркеров можно запустить на одну задачу?» — вопрос из категории Архитектура, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Оптимальное количество воркеров определяется типом задачи и доступными ресурсами.

Ключевые факторы:

  • CPU-bound задачи (например, обработка изображений, сложные вычисления): количество воркеров не должно превышать количество физических/логических ядер CPU. Иначе возникнет contention и общая производительность упадет.
  • I/O-bound задачи (запросы к БД, внешние API, работа с файловой системой): можно запускать значительно больше воркеров, так как они большую часть времени ожидают ответа от внешних систем. Эмпирическое правило — в 2-3 раза больше количества ядер.
  • Потребление памяти (RAM): Каждый процесс-воркер (например, PHP-FPM worker или процесс, запущенный через pcntl_fork()) потребляет память. Общее потребление не должно превышать доступную RAM.

Практический пример для PHP (обработка очереди):

// Упрощенный пример запуска ограниченного числа воркеров
$maxWorkers = (int) shell_exec('nproc'); // Получаем количество ядер
$queue = getJobsFromQueue();

$pids = [];
for ($i = 0; $i < min($maxWorkers, count($queue)); $i++) {
    $pid = pcntl_fork();
    if ($pid == -1) {
        die('Could not fork');
    } else if ($pid) {
        // Родительский процесс
        $pids[] = $pid;
    } else {
        // Дочерний процесс (воркер)
        processJob($queue[$i]);
        exit(0); // Важно завершить дочерний процесс
    }
}
// Родитель ждет завершения всех воркеров
foreach ($pids as $pid) {
    pcntl_waitpid($pid, $status);
}

В продакшене для управления воркерами используют специализированные системы: Supervisor для PHP-FPM пулов, RabbitMQ Consumer'ы, или очереди задач в Laravel (Horizon), которые сами управляют балансировкой нагрузки.