Импорт большого количества товара

Евгений

Для импорта CSV файлов, больших объемов обычно используют Ajax. Вызывают скрипт с передачей JSON параметров и результатов работы. Вызванный скрипт обрабатывает порцию записей и возвращает результат браузеру. Браузер показывает в зависимости от результата прогресс бар и вызывает скрипт снова. Так продолжается до окончания. Признак окончания браузер получает этим же (периодически вызываемым) скриптом.


Разработчики же shop-script в добавок к периодическому скрипту вызывают в самом начале скрипт который по словам службы сопровождения отслеживает окончание процесса. Тем самым создавая проблему от которой и хотели уйти порционной загрузкой CSV файла. На долгих загрузках (могут быть и более 10 минут), скрипт отваливается и окончания вы можете ждать бесконечно. Хотя по факту все закачано верно!

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

Считаю что такой импорт нужно исправлять. Кто что скажет?

P.S. На старом форуме в таком же треде ответил человек с ником Vladislav (я так понимаю разработчик) и потерялся.

2 июля 2015
  • Syrnik.com 2 июля 2015 05:54

    Как программист могу сказать, что предлагаемое вебассистом решение — очень красивое и является отличной модификацией предлагаемого вами, позволяя работать даже в условиях нестабильного соединения с сетью. Клиентская часть придумана классно. Серверная часть может притормаживать в зависимости от реализации. Не знаю, что там при импорте csv, у нас миграция с предыдущей версии до 90 тыс. товаров и 6 тыс. категорий работает (потом все-таки падает), правда после 30 тыс. начинает сильно тормозить, что в принципе и неудивительно, если посмотреть, как оно на сервере реализовано.

  • Евгений 2 июля 2015 06:09

    Что вы сказать то хотели? :)
    То что они молодцы или что "потом все-таки падает"?

    Хотелось бы получить комментарий от разработчика импорта.

  • Владислав Горлов 2 июля 2015 07:06

    "Падение" воспроизвести удалось — на длительных операциях бывает так, что скрипт не получает финальный отчет и зацикливается в его ожидании, получая пустой ответ. (Евгений, тестировалось на файлах, что вы отправляли в поддержку).

    Исправление будет в ближайшем обновлении (Заодно проверим и остальные аналогичные импорты/экспорты).

  • Евгений 2 июля 2015 07:18

    Просто прекрасные новости!
    Заранее благодарю за то что разобрались.

  • Леонид Вакуленко 2 июля 2015 07:56

    Мне кажется, это хороший повод рассказать, как архитектурно работает waLongActionController. Более-менее то же самое написано и в комментах к этому классу.

    Есть PHP контроллер и есть JS в браузере. Взаимодействуют они так.

    • [JS] запускает процесс [PHP]. [PHP] немедленно возвращает идентификатор processId нового процесса и не делает никакой реальной работы. Это должно произойти мгновенно и без задержек.
    • После того, как [JS] получил processId, задача [JS] - постоянно напоминать о себе и пинать [PHP], возобновляя работу процесса. Скажем, раз в 30 секунд. Ответ на пинок может прийти или не прийти. Потеря некоторых ответов не имеет особенного значения, если хотя бы иногда информация возвращается в браузер корректно. Главная инфа, которую отслеживает [JS] в ответе сервера - это закончен ли процесс или ещё продолжается. Пока не закончен, продолжаем пинать. Когда закончен, радостно уведомляем юзера, что всё готово. В качестве второстепенной инфы можно получать состояние прогресс-бара или что угодно ещё.
    • Итак, [PHP] раз в 30 секунд получает запрос со стороны [JS]. Логика при получении этого запроса следующая. Вызванный контроллер может стать либо Runner'ом, либо Messenger'ом с таким расчётом, чтобы Runner всегда мог быть только один.
      • Если [PHP] видит, что Runner есть и работает, то он становится Messenger'ом и немедленно возвращает информацию в [JS] о текущем состоянии процесса. Никакой работы Messenger не выполняет. Такие ответы приходят мгновенно и обновляют прогресс-бар в браузере.
      • Если [PHP] видит, что активного Runner'а нет (например, потому что тот сдох, превысив max_execution_time), контроллер сам становится Runner'ом и начинает выполнять работу. В браузер такой вызов контроллера ничего не отправит до самой своей героической смерти. Скорее всего, совсем ничего полезного не отправит.
    • Такая схема работы продолжается, пока вся работа не будет выполнена. С того момента, когда работа заканчивается, все вызовы [PHP] считаются Messenger'ами и возвращают в [JS] инфу о завершившемся процессе. Таких вызовов может быть много, если [JS] логике это по какой-то причине удобно. Завершившийся процесс будет храниться до тех пор, пока [JS] отдельным независимым способом не сообщит в [PHP] о том, что данные процесса больше не нужны. Например, [JS] может дожидаться, пока юзер скачает результат экспорта, и только после этого разрешит [PHP] их удалить.


    * * *

    Так вот. Описанный в первом посте "в самом начале скрипт", который работает 10 минут - это первый Runner, которому настройки PHP+nginx разрешили действовать 10 минут и более. Проблем он не создаёт: даже если он сдохнет и не отправит ничего в браузер (как собственно и должен), очень быстро запустится новый Runner и продолжит работу.

    Найденная ошибка, про которую говорил Владислав, специфична для конкретного импорта CSV, а не для waLongActionController'а в целом. На последнем шаге описанной выше схемы [JS] при определённых обстоятельствах не получал инфы о том, что процесс завершился. Это исправится в очередной версии плагина.

  • Syrnik.com 2 июля 2015 14:39

    В миграции, насколько помню, по крайней мере с WA 3xx, составлялась огромный массив id категорий и отношений id_категории→id_товара. Или что-то такое. Может старый_id→новый_id? Не помню точно. :-/ При over 50 тыс. элементов оно заметно тормозило при serialize/unserialize когда LongAction пытался сохранить/восстановить состояние. В конце концов скрипт умирал по таймауту в процессе восстановления состояния. :)

    Не знаю, как сейчас. Давно уже не что-то не мигрировали большой ассортимент. :)

  • Евгений Леман 2 июля 2015 14:43

    У меня в приложении была необходимость в waLongActionController. Но как-то до конца я с ним не разобрался. Уже не помню в чем была трудность. Но помню то, что сильно ругался из-за того, что подобному контроллеру не отведена отдельная статья в доках. С картинками и примерами. Это я как бы намекнул :)

  • Syrnik.com 2 июля 2015 15:02

    Евгений, там реально несложно и оч. удобно и надежно. Задумка отличная. :)

  • km 2 июля 2015 16:06

    За waLongActionController отдельное спасибо

  • Helen Helen 22 июля 2015 11:47

    А что скажете по поводу обнуления склада на 20 000 позиций. Ни один поставщик не присылает прайсы со строчками продуктов где кол-во НОЛЬ.

    Для того, чтобы скрыть товары, которые вышли из производства или в допроизводстве необходимо отсортировать их по наличию НОЛЬ на складе и скрыть, предварительно выкачав их и заново залив.

    Мы когда заливаем файл в 13 000 товаров на это уходит 10 часов времени. если дробить по 1000 около 6 часов.

  • Евгений 22 июля 2015 14:49

    А почему так долго? У меня прайс плюс остатки 55000 наименований. Закачиваю одним файлом, предварительно убрав из него все лишнии столбцы. Минут за 30 -40 вполне реально!

    Единственный минус, остатки и цены только по артикулу обновить можно, а вот Статус поменять нельзя... Нужно еще наименование или ссылка на товар!

  • Евгений 22 июля 2015 14:51

    А по поводу того что виснит под конец импорта это вообще не понятный баг, он может в 55000 наименований пройти до конца без проблем, а может в файле на 8000 позиций "зависнуть"

  • Евгений 23 июля 2015 05:21

    >10 часов времени

    Комп на хостинге тормозной или тарифный план. Основная нагрузка на MySQL

  • Вячеслав 24 июля 2015 13:07

    Импорт никакой, на хостингах стоят ограничения импорт их не обходит, на опенкарте обходит. Вебасист для лохов

  • creativit.ru 30 мая 2016 17:37

    Импортирую CSV (>800 000 товаров). Разбил на более мелкие кусочки. По началу всё загружалось достаточно бодро, но после 250 000 импорт товаров идёт со скоростью 5 товаров в минуту....

    У всех товаров есть две характеристики с уникальными значениями для каждого товара.

    Можно ли как-то оптимизировать добавление? Может быть порекомендуете какие-то индексы или еще что? ))))

  • > Можно ли как-то оптимизировать добавление?

    Ух ты. 800 тысяч это круто!

    Если это разовая операция, я бы попробовал вот что. Удалить все индексы из таблиц shop_product* до импорта, провести импорт, а по окончании добавить индексы обратно. Индексы ускоряют поиск по таблицам, но замедляют вставку строк.

  • creativit.ru 31 мая 2016 11:40

    Леонид, спасибо за комментарий!

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

  • BNP (Дмитрий) 31 мая 2016 12:43

    оО ... 800к товаров ... ebay или amazon наконец-то на шопскрипт перешли? =))

    Если не сложно, отпишитесь потом как шопскрипт справляется с таким кол-вом товаров.

Добавление новых комментариев к этой теме отключено.