Zip Create Process with Node Express of large ZIP packages
目标
我们站在一个小规模的站点上,用户(浏览器客户端)将在其中选择图像文件(每个文件284 KB),然后请求Node Express Server将其捆绑为ZIP以便下载到Web客户端。
问题与设计约束
-
最终的ZIP可能约为50 MB-5 GB。因此,我们想
在ZIP制作过程中为用户提供运行进度栏
建造。 (我们假设浏览器将针对
实际下载进度)。
-
虽然我们希望请求量少
(一次1-2个请求)。但是,我们不想完全占用我们的4个
核心服务器处理器,因此我们希望最大程度地减少占用快速服务器的同步调用。
-
给定ZIP的大小,我们不能期望zip仅在内存中组装
-
还有其他我们应该担心的问题吗?
题
我们假设将7zip作为子进程运行是不好的,因为关于将258KB文件添加到ZIP的数量我们不会获得任何运行状态。
那么,鉴于上面列出的设计约束/目标,下列哪个软件包对Node / ExpressJS非常友好?
-
封存器:https://www.npmjs.com/package/archiver
-
jszip:https://www.npmjs.com/package/jszip
-
easyzip:https://www.npmjs.com/package/easy-zip
-
expresszip:https://www.npmjs.com/package/express-zip
-
zipstream:https://www.npmjs.com/package/zip-stream
我在上面看到的是,大多数软件包首先收集文件,然后将它们最终确定到内存中,然后通过管道将它们传递给http请求(可能不适合5GB的数据,或者我丢失了什么)。有些人似乎可以使用磁盘,但问题是在添加每个文件时是否会发生更新事件?
其他人似乎完全不同步,我看不到每个文件添加到ZIP包后如何获得运行进度值。
-
我认为最简单的设计是运行一个子进程,该子进程将生成的zip文件放在磁盘上的临时文件中,并管理其自身的内存消耗。 然后,完成后,您可以从磁盘流式传输临时文件作为下载内容。 然后,您需要的是一个可执行文件,该文件在将zip文件构建到stdout方面提供了一些进展。 由于它在另一个进程中运行,因此您不必担心它如何在处理器上完成其工作,因为它不会以任何方式捆绑nodejs。 从本质上讲,压缩会占用大量CPU,因此您无法避免这种情况。
-
@ jfriend00我在目标计算机上可用的全部是7zip,当我尝试--bb日志记录开关时,它只是在归档后打印出文件。 也许我错过了一个开关? sevenzip.osdn.jp/chm/cmdline/switches/index.htm
上面列出的软件包中。大多数都不适合
-
JSZIP主要用于浏览器
-
EasyZip是JSZIP的节点包装,但未提供
创建过程中的进度通知
-
Express-Zip是一种内存中表达友好的RES解决方案(但
可能无法处理我们正在谈论的ZIP的大小)
-
ZIP-Stream是Archiver下的基础实用程序。封存者有
排队服务,所以应该只是用户归档程序
-
YAZL可能有效,但是界面对于进度而言更加复杂
跟踪比存档
我们选择了Archiver,因为它具有所需的大多数功能:
-
表达友好
-
低内存占用
-
对于我们创建的特定图像档案,速度高达7ZIP(我们不需要压缩,文件很大等)。对于其他类型的档案,您的性能可能会受到25%的影响
-
它不允许您附加到现有档案(这是我们想要的功能之一),但是adm-zip可能会弥补这一差距
至于7zip解决方案。我们倾向于不喜欢从生成的子进程中读取标准输出流的内脏。
-
在流中找到字符串很麻烦
-
它导致上下文切换读取流,
-
您有一个易碎的解决方案试图处理输出流输出的内容(例如,对于7zip,它有时会使计数器反跳30%,有时反跳1%),以及其他易碎解决方案的来源。
-
真正取决于您的服务器性能配置文件的一个问题是,node-archiver似乎正在进程内运行。如果您要同时执行大量操作或一次为大量用户提供服务,那么您可能会真正受益于将存档处理移出流程(例如在另一个流程中运行7zip)。而且,在有负载的情况下,与从一个过程到另一个过程的标准输出额外成本相比,这将提供更多的可伸缩性优势。解析输出流是一个纯粹可解决的问题(它只是完全了解它并编写代码来处理它的问题)。
-
因此,当然更喜欢node-archiver为您提供的进度接口,但是要注意它是否满足您的可伸缩性需求。您提到的7zip问题是完全可以解决的。需要编写更多代码,但是如果您希望将更多的CPU放在问题上或从快速处理中卸载zip处理以释放它来释放它,从而可以更快地响应其他Web请求,则可以解决。
-
我帖子的第一行内容是:"我们站起来的网站数量很少",所以不行,扩展到大量同时用户并不属于体系结构或问题空间。
-
然后您说"但是,我们不想完全占用我们的4核心服务器处理器",所以我不会说您的要求非常明确。 如果您对自己所拥有的感到满意,那就很好。 我的评论适用于其他人(可能会有稍微不同的愿望),他们一起阅读了这篇文章。
-
它是一个I / O绑定的问题。 我不想要一个试图压缩已经压缩过的d图像并将其变成CPU限制问题的软件包。 在人们眼中看不出来之前,只能在SO中提出一小部分问题。
-
好的,明白了。
We assume that running 7zip as a child process is bad, since we would not get any running status as to how many of the 258KB files had been added to the ZIP.
这似乎是一个错误的假设。
这样的命令行将在添加每个新文件时显示在stdout上添加到存档的每个文件的进度:
1
| 7z a -bsp1 -bb3 test.7z * |
因此,您可以使用子进程模块从node.js启动该进程,并且应该能够捕获发生的stdout进度。您将需要使用spawn,而不是exec,这样您就可以实时获取stdout数据。
作为子进程运行此进程将使您的nodejs进程可以自由处理其他请求,并使子进程可以独立于nodejs来管理自己的内存。
7zip程序可处理具有适当内存使用量的超大存档和文件。借助正确的标记来获得stdout的进度并将其作为子进程运行,它似乎可以满足您的所有要求。
-
谢谢@jfriend。我有时间对此进行自己的研发。两种方法都有优点和缺点。使用磁盘来暂存数据(并可以处理64位zip容器)的NPM程序包使用节点Zlib nodejs.org/api/zlib.html,这可以节省繁琐的过程上下文交换(比7zip生成方法更多)。我将同时测试7zip和archiver(具有良好的进度监视功能)并进行报告。
-
顺便说一句,-bb3或只是-bb1都没有帮助,如上所述,它没有显示进度。这是我正在使用的7zip -a -tzip -mx1 -mmt- = on -r -bsp1
-
哦,是的,我不认为7zip可以实现增量进度是因为:superuser.com/questions/702122/
-
@ Dr.YSG-在我的命令窗口中,它显示添加时正在添加到存档中的每个文件。我认为这是一个粗略的进展。而且,它的信息比没有该标志时所能看到的更多。如果您正在寻找其他东西,那么请在您的问题中更具体一些。我以为我在帮助您并向您提供您不知道的信息。我想我只是在浪费时间。
-
您正在提供帮助,这就是为什么我刚才说谢谢(请参阅顶部评论)。我评论的是-bb3标志本身很有用。实际上,您可以将其删除。实际提供进度的是-bsp1标志(bb标志在压缩结束时显示结果)。
-
@ friend00,由于您是meta成员,所以也许您知道。有没有一种方法可以给您加分,但是对我来说,我可以提供自己的答案,以更好地映射我的问题,并且对大多数人来说是更合理的方法吗? (即,我发现node-archiver的效果更好,并且至少与7zip一样快)。
-
@ Dr.YSG-我本人实际上并未提供赏金(我主要回答问题,而不是问他们),但是帮助中心内的帖子说:"赏金期为7天。赏金的最短持续时间至少为1天。赏金结束后,有24小时的宽限期来手动授予赏金。只需单击每个答案旁边的赏金授予图标,即可将其赏金永久性地授予答卷人。(您不能将赏金授予自己的赏金回答。)"。因此,听起来您可以对一个答案授予赏金,然后接受您自己的答案。
-
@ Dr.YSG-并且,如此处在meta上所述,您可以接受您自己的答案,但可以将悬赏金授予对您有帮助的其他答案。