2011-05-04 55 views
2

我们使用PHP和CodeIgniter从数百个源中导入数百万个图像,在本地调整大小,然后将大小调整后的版本上传到Amazon S3。然而,这个过程需要比预期更长的时间,我们正在寻找替代品来加快速度。欲了解更多详情:将数百万张图像导入,调整大小并上传到Amazon S3

  • 查找是在我们的MySQL数据库表中对尚未调整大小的图像进行的。结果是一组图像。
  • 每个图像都使用cURL单独导入,并在处理期间临时托管在我们的服务器上。它们是本地导入的,因为该库不允许调整大小/裁剪外部图像。根据一些测试,从不同外部输入源输入时的速度差异一直在80-140秒之间(对于整个过程,每次测试使用200个图像),所以外部源可以明显减慢速度。
  • 当前的图像是使用image_moo library,它可以创建一个CodeIgniter S3 library
  • 的S3网址为新调整大小图像的图像
  • 调整后的图像上传到Amazon S3的副本,然后保存在数据库调整表,之后开始下一个图像

该过程每个图像需要0.5-1秒,这意味着所有当前图像将需要一个月的时间来调整大小并上传到S3。这个问题的主要问题是我们不断增加图像的新来源,并预计在2011年底之前至少有3000万到5000万的图像,而目前的5月初的400万。

我注意到了StackOverflow中的一个答案,它可能是我们的解决方案的一个很好的补充,其中图像是resized and uploaded on the fly,但由于我们不希望人们访问页面时出现任何不必要的延迟,因此我们需要确保尽可能多的图像尽可能已经上传。除此之外,我们需要多种尺寸的图像格式,目前只能上传最重要的格式,因为这个速度问题。理想情况下,每个导入的图像至少要有三种尺寸格式(例如,一个缩略图,一个正常尺寸和一个大尺寸)。

有人建议几天前批量上传到S3--任何这种节省的经验都会有帮助。

如果您有类似流程的经验,回答问题的任何部分将会有所帮助。部分代码(简体)

$newpic=$picloc.'-'.$width.'x'.$height.'.jpg'; 
$pic = $this->image_moo 
     ->load($picloc.'.jpg') 
    ->resize($width,$height,TRUE) 
    ->save($newpic,'jpg'); 
if ($this->image_moo->errors) { 
    // Do stuff if something goes wrong, for example if image no longer exists - this doesn't happen very often so is not a great concern 
} 
else { 
     if (S3::putObject(
     S3::inputFile($newpic), 
     'someplace', 
     str_replace('./upload/','', $newpic), 
     S3::ACL_PUBLIC_READ, 
     array(), 
     array( 
     "Content-Type" => "image/jpeg", 
    ))) 
{ // save URL to resized image in database, unlink files etc, then start next image 
+0

您可以通过Etsy在批量处理数百万张图像方面的经验来学习。请参阅:https://codeascraft.com/2010/07/09/batch-processing-millions-of-images/ – EdgeCaseBerg 2015-07-01 15:53:14

回答

3

为什么没有在服务器上添加一些包装逻辑,可以让你定义范围或图像组,然后运行该脚本几次。如果你可以在不同的图像集上同时运行其中的四个进程,那么它将以四倍的速度完成!

如果您在试图通过一个非常大的积压项目时遇到困难,那么您可以考虑启动一些Amazon EC2实例并使用它们进一步并行化流程。

+1

我同意。必须有某种方法来分解可以并行处理的问题。 EC2实例似乎是一个坚实的想法。某种地图/缩小型概念将在此处起作用。 – 2011-05-04 16:58:48

1

我建议你将你的脚本分成两个并发运行的脚本。人们可以将远程图像提取到本地源,只需对尚未在本地处理或缓存的任何/所有图像执行此操作即可。由于远程数据源会为请求添加一点点延迟,因此您将不断获取远程图像,而不仅仅是在处理每一个图像时都会这样做。

同时您使用第二个脚本来调整任何本地缓存的图像的大小并将其上传到Amazon S3。或者,您也可以使用一个脚本来调整本地文件的大小,然后再将另一个调整大小的文件上传到S3。

第一部分(获取远程源图像)将大大受益于运行多个并发实例,如James C上述建议。