Процесс создания Zip с помощью Node Express для больших пакетов ZIP

Цель

Мы создаем небольшой сайт, на котором пользователи (клиент-браузер) выбирают файлы изображений (284 КБ на файл), а затем запрашивают сервер Node Express для объединения их в ZIP-файл для загрузки в веб-клиент.

Проблемы и ограничения дизайна

  • Результирующий ZIP-файл может иметь размер порядка 50 МБ - 5 ГБ. Поэтому мы хотели бы предоставить пользователю работающий индикатор выполнения во время создания ZIP-файла. (Мы предполагаем, что браузер будет постоянно обновлять информацию о ходе фактической загрузки).
  • Пока мы ожидаем небольшой объем запросов (1-2 запроса за раз). Однако мы не хотим полностью загружать процессор нашего 4-ядерного сервера, поэтому мы хотим свести к минимуму синхронные вызовы, которые задействуют экспресс-сервер.
  • Учитывая размер ZIP, мы не можем ожидать, что zip будет собран только в памяти.
  • Есть ли какие-либо другие проблемы, о которых нам следует беспокоиться?

Вопрос

Мы предполагаем, что запуск 7zip в качестве дочернего процесса — это плохо, поскольку мы не получим никакого рабочего статуса относительно того, сколько файлов размером 258 КБ было добавлено в ZIP.

Итак, какие из следующих пакетов очень дружественны к Node/ExpressJS, учитывая ограничения/цели дизайна, перечисленные выше?

Что я вижу выше, так это то, что большинство пакетов сначала собирают файлы, а затем финализируют их в памяти, а затем направляют их в http-запрос (вероятно, не подходит для 5 ГБ данных или я что-то упустил). Некоторые, кажется, могут использовать диск, но вопрос будет в том, будут ли получать события обновления при добавлении каждого файла?

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


person Dr.YSG    schedule 23.05.2017    source источник
comment
Я думаю, что самый простой дизайн - запустить дочерний процесс, который помещает полученный zip-файл на диск во временный файл и управляет собственным потреблением памяти. Затем, когда это будет сделано, вы можете передать временный файл с диска в качестве загрузки. Затем все, что вам нужно, это исполняемый файл, который предлагает какой-то прогресс в построении zip-файла для stdout. Поскольку он работает в другом процессе, вам не нужно беспокоиться о том, как он выполняет свою работу с точки зрения процессора, потому что он никоим образом не свяжет nodejs. Сжатие по своей природе несколько интенсивно использует процессор, поэтому вы не можете избежать этого.   -  person jfriend00    schedule 23.05.2017
comment
@ jfriend00 все, что у меня есть на целевой машине, это 7zip, и когда я попробовал переключатель ведения журнала --bb, он просто распечатывает файлы после создания архива. Может есть переключатель, который я упускаю? sevenzip.osdn.jp/chm/cmdline/switches/index.htm   -  person Dr.YSG    schedule 26.05.2017


Ответы (2)


Из пакетов, перечисленных выше. Большинство не подходило

  • JSZIP в основном для браузера
  • EasyZip — это оболочка узла для JSZIP, но она не предоставляет уведомления о ходе выполнения во время создания.
  • Express-Zip is an in-memory express friendly RES solution (but probably would not handle the size of the ZIP we are talking about)
    • ZIP-Stream is underlying utility underleath Archiver. Archiver has the queuing services, so one should just user archiver
  • YAZL может работать, но интерфейс более сложен для отслеживания прогресса, чем Архиватор.

Мы выбрали Архиватор, так как он обладал большинством желаемых функций:

  • Экспресс Дружелюбный
  • малый объем памяти
  • так же быстро, как 7ZIP для определенных архивов изображений, которые мы создаем (нам не нужно сжимать, файлы большие и т. д.). Вы можете потерять 25% производительности для других типов архивов.
  • Он не позволяет вам добавлять файлы в существующие архивы (это была одна из функций, которую мы хотели), но adm-zip может обеспечить эту брешь.

Что касается решения 7zip. Нам не нравится читать внутренности стандартного потока вывода из порожденного дочернего процесса.

  • Беспорядочно находить строки в потоках
  • это заставляет контекстные переключатели читать поток,
  • у вас есть хрупкое решение, пытающееся справиться с тем, что выдает поток вывода (например, в случае 7zip он иногда перескакивает через счетчик на 30%, иногда на 1%), а также другие источники хрупких решений.
person Dr.YSG    schedule 30.05.2017
comment
Один вопрос, который действительно зависит от профиля производительности вашего сервера, заключается в том, что кажется, что node-archiver работает в процессе. Если вы делаете много этого или обслуживаете много пользователей одновременно, вы можете действительно извлечь выгоду из переноса обработки архива из процесса (как при запуске 7zip в другом процессе). И при нагрузке это дало бы гораздо больше преимуществ масштабируемости, чем дополнительные затраты на передачу stdout от одного процесса к другому. Работа с разбором выходного потока — это чисто решаемая проблема (это просто вопрос полного понимания и написания кода для ее обработки). - person jfriend00; 30.05.2017
comment
Так что, конечно, можно предпочесть интерфейс прогресса, который предоставляет вам node-archiver, но будьте осторожны с тем, соответствует ли он вашим потребностям в масштабируемости или нет. Упомянутые вами проблемы с 7zip полностью решаемы. Нужно написать больше кода, но это решаемо, если вы хотите использовать больше процессоров для решения проблемы или разгрузить обработку zip из вашего экспресс-процесса, чтобы освободить его для более быстрой обработки других веб-запросов. - person jfriend00; 30.05.2017
comment
Самая первая строка в моем посте гласит: Мы поддерживаем сайт с небольшим объемом. Так что нет, масштабирование до большого количества одновременных пользователей не является частью архитектуры или проблемной области. - person Dr.YSG; 31.05.2017
comment
А затем вы говорите: «Однако мы не хотим полностью связывать наш 4-ядерный серверный процессор, поэтому я бы не сказал, что ваше требование действительно очень ясное. Если вы довольны тем, что имеете, это нормально. Мои комментарии относятся к другим (у которых могут быть немного другие желания), которые приходят и читают это. - person jfriend00; 31.05.2017
comment
Это проблема, связанная с вводом-выводом. Я не хотел, чтобы пакет пытался сжать уже сжатые изображения d и превратил это в проблему, связанную с процессором. Можно дать только небольшую часть проблемы в SO, прежде чем глаза людей остекленеют. - person Dr.YSG; 31.05.2017
comment
Хорошо понял. - person jfriend00; 31.05.2017

Мы предполагаем, что запуск 7zip в качестве дочернего процесса — это плохо, поскольку мы не получим никакого рабочего статуса относительно того, сколько файлов размером 258 КБ было добавлено в ZIP.

Похоже, это ложное предположение.

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

7z a -bsp1 -bb3 test.7z *

Таким образом, вы можете запустить его из node.js, используя дочерний модуль процесса, и вы сможете фиксировать ход выполнения stdout по мере его возникновения. Вам нужно будет использовать spawn, а не exec, чтобы вы могли получать данные stdout в реальном времени, когда это происходит.

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

Программа 7zip обрабатывает чрезвычайно большие архивы и файлы с соответствующим использованием памяти. С правильными флагами для получения прогресса в stdout и запуска его как дочернего процесса он, похоже, соответствует всем вашим требованиям.

person jfriend00    schedule 26.05.2017
comment
Спасибо @jfriend. У меня есть время, чтобы заняться своими исследованиями и разработками. У обоих методов есть плюсы и минусы. Пакеты NPM, которые используют диск для хранения данных (и могут обрабатывать 64-битные zip-контейнеры), используют узел Zlib nodejs. org/api/zlib.html , что может сэкономить тяжелую замену контекста процесса по сравнению с подходом создания 7zip. Я собираюсь протестировать как 7zip, так и архиватор (у которого есть хороший мониторинг прогресса) и отчитаться. - person Dr.YSG; 29.05.2017
comment
Кстати, -bb3 или просто -bb1 не помогает, как говорится, не показывает прогресс. вот что я использую для 7zip -a -tzip -mx1 -mmt-=on -r -bsp1 - person Dr.YSG; 29.05.2017
comment
О да, причина, по которой я не думал, что 7zip может выполнять постепенный прогресс, заключалась в следующем: cmd" title="как показать ход распаковки 7zip внутри cmd">superuser.com/questions/702122/ - person Dr.YSG; 29.05.2017
comment
@ Dr.YSG - в моем окне команд он показывает каждый файл, добавляемый в архив, по мере его добавления. Я считаю это грубым уровнем прогресса. И это гораздо больше информации, чем я видел без этого флага. Если вы ищете что-то другое, пожалуйста, будьте НАМНОГО конкретнее в своем вопросе. Я думал, что помогаю и предлагаю вам информацию, которую вы еще не знали. Думаю, я просто трачу свое время. - person jfriend00; 29.05.2017
comment
Вы помогаете, и именно поэтому я сказал ранее спасибо (см. верхний комментарий). То, что я комментировал, было то, что флаг -bb3 сам по себе полезен. На самом деле вы можете удалить его. Это флаг -bsp1, который фактически показывает прогресс (флаг bb показывает результаты в конце сжатия). - person Dr.YSG; 29.05.2017
comment
@friend00, Поскольку вы являетесь мета-членом, возможно, вы знаете. Есть ли способ дать вам бонусный кредит, но для меня предоставить свой собственный ответ, который лучше соответствует моей проблеме и является более разумным подходом для большинства людей? (т.е. я обнаружил, что нод-архиватор работает лучше и по крайней мере так же быстро, как 7zip) для моих наборов данных. - person Dr.YSG; 29.05.2017
comment
@Dr.YSG - на самом деле я сам не предлагал награду (в основном я отвечаю на вопросы, а не задаю их), но этот пост в Справочном центре говорит: Период вознаграждения длится 7 дней. Баунти должны иметь минимальную продолжительность не менее 1 дня. После окончания вознаграждения есть льготный период в 24 часа, чтобы вручную присудить вознаграждение. Просто щелкните значок вознаграждения рядом с каждым ответом, чтобы навсегда присудить вознаграждение ответившему. (Вы не можете присудить награду за свой собственный ответ.). Итак, похоже, что вы можете назначить награду за один ответ, а затем принять свой собственный ответ. - person jfriend00; 30.05.2017
comment
@Dr.YSG - И, как описано здесь, на мете, вы можете принять свой собственный ответ, но присудить вознаграждение другому ответу, который вам помог. - person jfriend00; 30.05.2017