Как оптимизировать foreach или запустить параллельное выполнение?
Добрый день. У меня есть база из 30к продуктов.
Мне нужно каждый продукт запросить из микросервиса и записать результат в массив.
Я пробовал для начала делать 100 итераций, прогоняю массив с продуктами через foreach.
В среднем одна иттерация занимает 7 сек а 100 иттераций 4,2 сек. На 30к продуктов выйдет больше 30 часов. И это еще без функционала, который что-то должен делать с этими массивами, там для одного продукта время увеличивается до 7 сек.
Поделитесь опытом разработки подобных задач. Как можно оптимизировать процесс? Может есть какие-то проверенные, подходящие библиотеки для асинхронности, параллельности?
Мне нужно каждый продукт запросить из микросервиса и записать результат в массив.
Можете еще шире и более детальнее объяснить, почему не запросить товар из Базы напрямую? Что за массив, для чего все?
Может тут и кроется хороший рецепт, когда точно станет понятно, что вы делаете
Максим Федоров, есть база продуктов, 30 тысяч позиций, массив из 30к айдишников, по которым будем запрашивать. Нужно все эти продукты обновлять раз в неделю и создавать документ. Но перед этим нужно эти данные запросить у erp.
Т.е нужно 30 тысяч запросов делать в erp через микросервис и отдавать массивы с полями для создания документа каждому.
Максим Федоров, erp наша, да, на другом сервере. Но общение с ней мы ведем через микросервиса, который имеет rest и отдает нам данные для каждого продукта.
Если вы используете обычный php без расширений open swoole, rode runner etc.. то для вас есть только 1 способ добиться асинхронного выполнения кода. Это очереди, https://www.rabbitmq.com, https://kafka.apache.org
Если вы используете Laravel то просто установите Laravel Horizon
Дмитрий, через консоль? Верно.
На крон обязательно влепим.
Но в идеале хотелось бы оптимизировать процесс, что бы все таки избежать 30 часовое выполнение.
Alex Lapikov, можно запустить команду в кроне - которая задачу разобьет на 20 и запустит кучу php команд в фоновом режиме черех nohup. Без очередей и swoole, reactphp и прочего.
Оно конечно лучше бы в erp добавить метод массовой отдачи нужных вам данных, но ежели невозможно, то делайте параллельные запросы насколько сервер выдержит.
Дмитрий, Не мешает, но тут по логике данные приходят с api, значит надо сначала их все стянуть а потом еще позаботиться о мьютексе что бы разные процессы не делали одно и тоже, мое имхо: потратить 5 минут на то что бы развернуть рэбит приятнее, к тому же потом его можно использовать для других задач
Blindovich, в задаче написано "у меня есть база". разбить базу на куски - в чем она бы не была, вопрос не сложный. Добиться одноразовости запуска тоже как бы не очень сложно - добавить flock. Тащить в стэк новый инструмент ради простой задачи - решение далеко не всегда правильное.