导入,调整大小并将数百万张图像上传到Amazon S3

时间:2011-05-04 16:48:45

标签: php codeigniter image-processing amazon-s3

我们正在使用PHP和CodeIgniter从数百个来源导入数百万个图像,在本地调整大小,然后将调整后的版本上传到Amazon S3。然而,这个过程花费的时间远远超过预期,我们正在寻找加快速度的替代方案。有关详细信息:

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

此过程每张图片需要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

2 个答案:

答案 0 :(得分:3)

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

如果你现在被迫试图通过一个非常大的积压,你可以考虑启动一些Amazon EC2实例并使用它们来进一步并行化这个过程。

答案 1 :(得分:1)

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

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

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