我有一个正在进行的图像处理任务列表,使用ImageMagick合成大型单个图形文件(每个20MB)。这些图像当前存储在S3上(总共约2.5GB)。
我想使用多个EC2实例来处理任务、合成图像并将输出文件上传到S3。
此设置的问题是ImageMagick需要文件库是本地的(在计算机上)。目前图像在S3上,这意味着每个实例都需要从S3下载图像的副本,这会减慢整个过程。
将此图像库共享给所有节点的最佳方式是什么?
还要考虑以下几点:
-
您可以通过以特殊格式
MPR:
(Magick Pixel Register)"保存"任何输入图像,完全在内存中对ImageMagick文件进行任何处理。有关详细信息,请参阅以下答案:"ImageMagick在一次调用中执行多个操作"> -
ImageMagick可以通过
http://
访问远程图像。 -
您可以将ImageMagick操作的批放入一个命令行中,该命令行也可以生成多个输出文件,还可以使用括号语法将该命令行分段为子进程或副进程:
... ( IM side process ) ...
表示子进程/副进程。
如何简化整个流程在很大程度上取决于你到底想做什么。然而,
MPR:
/MPC:
技术对此非常有用,并且可能避免或最小化使用多个EC2实例的需要- 你无法绕过以某种方式将输入像素运送到ImageMagick实例的步骤,该实例应该处理这些像素(因此"下载副本"总是必须发生)
- 您可以将输入存储在内存中的一系列
MPR:xy1
、MPR:xy2
等标签下,然后从构造良好的ImageMagick命令行快速访问所有这些,从而最大限度地减少下载次数,该命令行可以执行任意数量的合成
示例
举个例子。考虑使用10个TIFF,并且您希望从这些TIFF创建3个不同的PDF文件,每个PDF包含由10个TIFF组成的不同页面集。通常你会运行3个命令:
convert 1.tif 3.tif 4.tif 8.tif 9.tif 10.tif -compress jpeg -quality 70 1out1.pdf
convert 2.tif 3.tif 4.tif 7.tif 8.tif 9.tif -compress jpeg -quality 70 1out2.pdf
convert 3.tif 4.tif 5.tif 7.tif 8.tif 10.tif -compress jpeg -quality 70 1out3.pdf
这3个命令每个都必须加载6个TIFF文件(一些TIFF,如3.tif
,在所有3个命令中都使用)。这是18个I/O事件。
现在考虑这个命令替代方案,它会运行得更快(我相信):
convert
1.tif +write mpr:t1 +delete
2.tif +write mpr:t2 +delete
3.tif +write mpr:t3 +delete
4.tif +write mpr:t4 +delete
5.tif +write mpr:t5 +delete
6.tif +write mpr:t6 +delete
7.tif +write mpr:t7 +delete
8.tif +write mpr:t8 +delete
9.tif +write mpr:t9 +delete
10.tif +write mpr:t10 +delete
( mpr:t1 mpr:t3 mpr:t4 mpr:t8 mpr:t9 mpr:t10
-compress jpeg -quality 70 +write 2out1.pdf )
( mpr:t2 mpr:t3 mpr:t4 mpr:t7 mpr:t8 mpr:t9
-compress jpeg -quality 70 +write 2out2.pdf )
( mpr:t3 mpr:t4 mpr:t5 mpr:t7 mpr:t8 mpr:t10
-compress jpeg -quality 70 +write 2out3.pdf )
null:
此命令只加载10个TIFF中的每一个一次(总共10个I/O事件)。然后,它将每个TIFF写入带有适当标签的MPR:
文件,然后从图像序列中删除初始TIFF。
在这一初始准备之后,ImageMagick将按顺序运行3个不同的括号-d侧处理管道,将所需的输出页面加载为MPR:
图像,并从每个页面创建PDF。
上述示例可能过于有限,无法通过使用MPR:
来展示可测量的优势。因为这个命令也可以获得相同的结果:
convert
1.tif
2.tif
3.tif
4.tif
5.tif
6.tif
7.tif
8.tif
9.tif
10.tif
( -clone 0,2-3,7-9 -compress jpeg -quality 70 +write 3out1.pdf )
( -clone 1-3,6-8 -compress jpeg -quality 70 +write 3out2.pdf )
( -clone 2-4,6-7,9 -compress jpeg -quality 70 +write 3out3.pdf )
null:
然而,还有一个可能获得一些性能胜利的挂钩:-compress jpeg -quality 70
被应用于每个6个(克隆的、原始的)图像3次。
如果在TIF写入MPR寄存器之前将此操作应用于TIF,则可能会保存一些CPU周期。通过这种方式,我们仅将该操作应用于10个畅通节能法。稍后,当我们写出PDF时,我们不再需要应用它:
convert
-respect-parentheses
1.tif -compress jpeg -quality 70 +write mpr:t1 +delete
2.tif -compress jpeg -quality 70 +write mpr:t2 +delete
3.tif -compress jpeg -quality 70 +write mpr:t3 +delete
4.tif -compress jpeg -quality 70 +write mpr:t4 +delete
5.tif -compress jpeg -quality 70 +write mpr:t5 +delete
6.tif -compress jpeg -quality 70 +write mpr:t6 +delete
7.tif -compress jpeg -quality 70 +write mpr:t7 +delete
8.tif -compress jpeg -quality 70 +write mpr:t8 +delete
9.tif -compress jpeg -quality 70 +write mpr:t9 +delete
10.tif -compress jpeg -quality 70 +write mpr:t10 +delete
( mpr:t1 mpr:t3 mpr:t4 mpr:t8 mpr:t9 mpr:t10 4out1.pdf )
( mpr:t2 mpr:t3 mpr:t4 mpr:t7 mpr:t8 mpr:t9 4out2.pdf )
( mpr:t3 mpr:t4 mpr:t5 mpr:t7 mpr:t8 mpr:t10 4out3.pdf )
null:
更新
Mark Setchell的评论很到位。在他提到这一点之前,我忽略了这一点。运行这样的命令可能更快(当然也更少):
convert
-respect-parentheses
-compress jpeg -quality 70
1.tif +write mpr:t1 +delete
2.tif +write mpr:t2 +delete
3.tif +write mpr:t3 +delete
4.tif +write mpr:t4 +delete
5.tif +write mpr:t5 +delete
6.tif +write mpr:t6 +delete
7.tif +write mpr:t7 +delete
8.tif +write mpr:t8 +delete
9.tif +write mpr:t9 +delete
10.tif +write mpr:t10 +delete
( mpr:t1 mpr:t3 mpr:t4 mpr:t8 mpr:t9 mpr:t10 5out1.pdf )
( mpr:t2 mpr:t3 mpr:t4 mpr:t7 mpr:t8 mpr:t9 5out2.pdf )
( mpr:t3 mpr:t4 mpr:t5 mpr:t7 mpr:t8 mpr:t10 5out3.pdf )
null:
不过,如果你想决定使用哪种建议的命令,你必须在自己的环境中使用自己的图像运行自己的基准测试。