我尝试过几个Imagemagick包装器库和一些S3库。由于性能差异很大,我无法选择最佳概念。
我已经确定了节点库“gm”,这是一个很好的工作和很好的文档。
对于S3,我已经尝试了亚马逊自己的AWS库以及“S3-Streams”
编辑:我刚刚发现AWS库可以处理流。我想这是一个新功能s3.upload(或者我只是错过了它?)。无论如何,我抛弃了 s3-streams ,它使用了更复杂的s3uploadPart。 切换库流后,等同于在我的测试用例中上传缓冲区。
我的测试用例是将2MB jpg文件拆分成大约30个512px磁贴,并将每个磁贴发送到S3。 Imagemagick通过crop命令有一种非常快速的自动生成方法。不幸的是,我没有找到任何可以从自动生成的磁贴中捕获多文件输出的节点库。相反,我必须通过为每个图块单独调用crop命令来循环生成图块。
我会在详细信息之前提供总时间:
A :85秒(s3-streams)
A :34秒(aws.s3.upload)(编辑)
B :35秒(缓冲区)
C :25秒(并行缓冲区)
显然,在这种情况下缓冲区比流更快。我不知道 gm 或 s3-streams 是否有错误的流实现,或者我是否应该调整一些东西。现在我将使用解决方案B.C甚至更快,但会占用更多内存。
我在低端数字海洋Ubuntu机器上运行它。这就是我的尝试:
:一种。生成切片并逐个流式传输
我有一个用裁剪信息准备的数组,每个牌都有s3Key来生成
数组循环使用“async.eachLimit(1)”。我没有成功同时生成多个图块,因此限制了(1)。
生成切片时,会直接将这些切片流式传输到S3
伪代码:
async.eachLimit(tiles, 1, function(tile, callback) {
gm(originalFileBuffer)
.crop(tile.width, tile.height, tile.x, tile.y)
.stream()
.pipe(s3Stream({Key: tile.key, Bucket: tile.bucket})) //using "s3-streams" package
.on('finish', callback)
});
B中。生成缓冲区块并使用AWS包直接上传每个缓冲区
伪代码:
async.eachLimit(tiles, 1, function(tile, callback) {
gm(originalFileBuffer)
.crop(tile.width, tile.height, tile.x, tile.y)
.toBuffer(function(err, buffer) {
s3.upload(..
callback()
)
})
});
℃。与B相同,但将所有缓冲区存储在tile数组中,以便稍后在parallell中上传
伪代码:
async.eachLimit(tiles, 1, function(tile, callback) {
gm(originalFileBuffer)
.crop(tile.width, tile.height, tile.x, tile.y)
.toBufer(function(err, buffer) {
tile.buffer = buffer;
callback()
})
});
..在完成第一个每个循环后完成下一步。我似乎没有通过将限制推到10以上而获得速度。
async.eachLimit(tiles, 10, function(tile, callback) {
s3.upload(tile.buffer..
callback()
)
});
修改:根据Mark的要求提供更多背景信息 我最初省略了细节,希望能得到关于缓冲区与流的明确答案。
目标是通过节点/ Express API以响应的方式为我们的应用提供图像。 Postend db是Postgres。批量存储是S3。
传入的文件主要是照片,平面图和pdf文档。照片需要以多种尺寸存储,以便我能以响应的方式将它们提供给应用程序:缩略图,低分辨率,中等分辨率和原始分辨率。
平面图必须是瓷砖,所以我可以在应用中逐步加载它们(滚动图块)。全分辨率A1绘图可以是大约50 MPixels。
上传到S2的文件范围从50kB(图块)到10MB(平面图)。
文件来自各个方向,但始终作为流:
我并不热衷于暂时将文件放在本地磁盘上,因此只有缓冲区与流。如果我可以使用磁盘,我会使用IM自己的平铺功能来实现快速平铺。
为什么不是本地磁盘?
答案 0 :(得分:0)
经过一些修修补补后,我觉得有必要回答我自己的问题。
最初我使用npm包 s3-streams 来流式传输到S3。该软件包使用aws.s3.uploadPart。
现在我发现aws包有一个整洁的函数aws.s3.upload,它接受缓冲区或流。
切换到AWS自己的流媒体功能后,缓冲区/流上传之间没有时间差异。
我可能以错误的方式使用了s3-stream。但我也发现了这个库中可能存在的错误(重新调整文件> 10MB)。我发布了一个问题,但没有得到任何答案。我的猜测是,自 s3.upload 函数出现以来,该库已被放弃。
所以,回答我自己的问题:
缓冲区/流之间可能存在差异,但在我的测试用例中它们是相同的,这使得现在不是问题。
以下是每个循环中新的" save" -part:
let fileStream = gm(originalFileBuffer)
.crop(tile.width, tile.height, tile.x, tile.y)
.stream();
let params = {Bucket: 'myBucket', Key: tile.s3Key, Body: fileStream};
let s3options = {partSize: 10 * 1024 * 1024, queueSize: 1};
s3.upload(params, s3options, function(err, data) {
console.log(err, data);
callback()
});
感谢您的阅读。