Laravel Queue — Как настроить процессор FAST

Я использую Laravel 5.5 и пытаюсь настроить быструю обработку очереди. Я сталкиваюсь с одним контрольно-пропускным пунктом за другим.

Этот сайт является службой соответствия работодатель / работник. Поэтому, когда работодатель публикует вакансию, ему необходимо пройти через всех сотрудников нашей системы и вычислить ряд переменных, чтобы определить, насколько они соответствуют работе. Мы все это выяснили, но обработка одного занимает много времени, когда в системе работают тысячи сотрудников. Итак, я настроен написать пару таблиц. Первая — это простая таблица, которая определяет идентификатор позиции и статус. Вторая — это таблица, в которой перечислены все идентификаторы сотрудника, идентификатор должности и статус этого сотрудника, который обрабатывается. Это занимает всего несколько секунд, чтобы написать, а затем позволяет пользователю двигаться дальше в приложении.

Затем у меня есть другой сервер настройки для запуска cron каждую минуту, который проверяет наличие новых записей в первой таблице. При обнаружении он помечает его как начатый, а затем захватывает всех сотрудников, проходит через каждого сотрудника и запускает задание в очереди в Laravel. Задание, которое я определил, правильно отправляется в очередь и выполняется queue:work действительно обрабатывает работу должным образом. Это все проверено.

Однако проблема, с которой я сталкиваюсь, заключается в том, что я попробовал базу данных (MySQL), Redis и SQS для очереди, и все они очень медленные. Я использовал этот же сервер, чтобы попытаться управлять queue:work (используя Supervisor и пытаясь запустить до 300 процессов), но затем создал 3 клона, которые не запускают cron, а только запускают Supervisor (100 процессов на клон) и убивают Supervisor на первом сервере. С базой данных все будет нормально, хотя выполнение заданий из 10 тыс. Очередей займет несколько часов, но с SQS и Redis я получаю массу сбоев. Сценарии занимают слишком много времени или что-то в этом роде. Я проверил процессоры на клонах, на которых работают рабочие, и они едва достигают 40%, поэтому я не перегружаю серверы.

Я просто читал о Horizon, и я не уверен, поможет ли это ситуации. Я продолжаю пытаться найти информацию о том, как правильно настроить систему обработки очереди с Laravel, и просто продолжаю сталкиваться с большим количеством вопросов, чем ответов.

Кто-нибудь знаком с этим материалом и есть какие-либо советы о том, как правильно его настроить, чтобы он был очень быстрым и без сбоев (при условии, что в моем коде нет ошибок)?

ОБНОВЛЕНИЕ: Следуя некоторым другим советам, я решил поделиться некоторыми подробностями:

  1. Я использую Forge в качестве инструмента установки для серверов AWS EC2 с 2 ГБ оперативной памяти.
  2. Каждый из трех клонов имеет следующую рабочую конфигурацию:

    command=php /home/forge/default/artisan queue:work sqs --sleep=10 --daemon --quiet --timeout=30 --tries=3
    
    process_name=%(program_name)s_%(process_num)02d
    autostart=true
    autorestart=true
    stopasgroup=true
    killasgroup=true
    user=forge
    numprocs=100
    stdout_logfile=/home/forge/.forge/worker-149257.log
    
  3. База данных находится на Amazon RDS.

Мне любопытно, будет ли кеш Laravel работать с системой очередей. Есть элементы сценария с очередями, которые являются общими для каждого запуска, поэтому, возможно, если я поставлю эти данные в очередь с самого начала, это может сэкономить некоторое время. Но я не уверен, что это будет огромное улучшение.

1

Решение

Если мы игнорируем фактическую логику, обрабатываемую каждым заданием, и учитываем издержки только на выполнение заданий, система очередей Laravel может без труда обрабатывать 10 000 заданий в час, если не в несколько раз, в среде, описанной в этом вопросе, особенно с помощью бэкэнда Redis.

При типичной настройке очереди 100 рабочих процессов в очереди на блок кажутся чрезвычайно высокими. Если эти работы не проводят значительное количество времени в ожидание Состояние — например, задания, которые отправляют запросы к веб-службам по сети и используют только несколько миллисекунд для обработки ответа, — большое количество одновременно запущенных процессов фактически снижает производительность. Мы не многого выиграем, запустив более одного рабочего на процессорное ядро. Дополнительные работники создают накладные расходы, поскольку операционная система должна разделять и планировать время вычислений между всеми конкурирующими процессами.

Я проверил процессоры на клонах, на которых работают рабочие, и они едва достигают 40%, поэтому я не перегружаю серверы.

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

С базой данных все будет нормально, хотя выполнение заданий из 10 тыс. Очередей займет несколько часов, но с sqs и redis я получаю массу сбоев.

Я постараюсь обновить этот ответ, если вы добавите в вопрос сообщения об ошибках и любую другую связанную информацию.

Мне любопытно, будет ли кеш Laravel работать с системой очередей. Есть элементы сценария с очередями, которые являются общими для каждого запуска, поэтому, возможно, если я поставлю эти данные в очередь с самого начала, это может сэкономить некоторое время.

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

Кроме того, мы могли бы кэшировать повторно используемые данные в памяти. Когда мы инициализируем работника очереди, используя artisan queue:work, Laravel запускает процесс PHP и загружает приложение один раз за все рабочих мест, которые выполняет работник. Это отличается от жизненного цикла приложения для типичного веб-приложения PHP, в котором приложение перезагружается для каждый запрос и удаляет состояние в конце каждого запроса. Поскольку каждое задание выполняется в одном и том же процессе, мы можем создать объект, который кэширует данные общего задания в памяти процесса, возможно, путем привязки синглтона к контейнеру IoC, который задания могут считывать намного быстрее, чем даже кэш-память Redis, потому что мы избегаем накладные расходы, необходимые для извлечения данных из серверной части кэша.

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

Я просто читал о Horizon, и я не уверен, поможет ли это ситуации.

Horizon предоставляет сервис мониторинга, который может помочь отследить проблемы с этой настройкой. Это также может немного повысить эффективность, если приложение использует другие очереди, между которыми Horizon может распределять работу в режиме ожидания, но вопрос, похоже, не указывает на то, что это так.

Каждый из трех клонов имеет следующую рабочую конфигурацию:

command=php /home/forge/default/artisan queue:work sqs --sleep=10 --daemon --quiet --timeout=30 --tries=3

(Sidenote: для Laravel 5.3 и более поздних --daemon опция устарела, а queue:work по умолчанию команда выполняется в режиме демона.)

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]