Cresis
@Cresis

Как оптимизировать foreach или запустить параллельное выполнение?

Добрый день. У меня есть база из 30к продуктов.
Мне нужно каждый продукт запросить из микросервиса и записать результат в массив.
Я пробовал для начала делать 100 итераций, прогоняю массив с продуктами через foreach.
В среднем одна иттерация занимает 7 сек а 100 иттераций 4,2 сек. На 30к продуктов выйдет больше 30 часов. И это еще без функционала, который что-то должен делать с этими массивами, там для одного продукта время увеличивается до 7 сек.

Поделитесь опытом разработки подобных задач. Как можно оптимизировать процесс? Может есть какие-то проверенные, подходящие библиотеки для асинхронности, параллельности?
  • Вопрос задан
  • 170 просмотров
Пригласить эксперта
Ответы на вопрос 3
@Blindovich
Если вы используете обычный php без расширений open swoole, rode runner etc.. то для вас есть только 1 способ добиться асинхронного выполнения кода. Это очереди, https://www.rabbitmq.com, https://kafka.apache.org
Если вы используете Laravel то просто установите Laravel Horizon
Ответ написан
@masterfreelance
программист со стажем
Ответ написан
Комментировать
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Асинхронка - это далеко не всегда фоновые задачи. Хотя если считать любое приложение умеющее в "одновременно" - фоновой задачей - то да. Даже браузер параллельку делает, обращаясь к штуке под названием WebApis в каждом шаге отрисовочного event-loop если хоть что-то висит в ожидании на этом шаге.

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

Это значит вы запрашиваете записи не по одной, а делаете функцию, которая очень любит foreach а данные хранятся не в переменной value, а в $values.

В этом случае ваша логика уже представляет собой не действие от а до я, а сначала циклом сделать для всех А, потом циклом сделать Б, потом циклом сделать В. И вот на каком-то из этих циклов вы втыкаете туда multicurl/guzzle, чтобы самую длительную (но не самую тяжелую) выполнить сразу в 100 потоков и получить 100 ответов.

В принципе авторы выше подсказали решение проще, ибо долго пояснять иное. Они сказали - чем переписывать логику, проще запустить 100 действий А-Я и для этого применить очереди, а знач их настроить, понять, поиграться, столкнуться с приколами и нежданчиками. По мне начать стоит с переписывания слабого места в этом скрипте на циклы, понять что можно "работать с пачками", но в компаниях это как правило не любят - переписывание - это всегда косяки, поэтому легче запустить уже написанное в поточном режиме (и получить серверные косяки, которые вас и добьют :( ), чем попробовать написать действие для "пачки" вместо "действия для одной"
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы