亚马逊AWSSDKforPHP太慢了

时间:2012-09-17 19:30:42

标签: php amazon-s3 amazon-web-services

Amazon AWSSDKforPHP太慢

你好,

我使用Amazon AWSSDKforPHP将我的Web应用程序与S3连接。但是,流程存在问题或者向服务发出请求会导致此过慢。

例如,我有这段代码:

// Iterate an array of user images
foreach($images as $image){
    // Return the Bucket URL for this image
    $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
}

假设$ images是一组用户图片,这将返回一个名为$ urls的数组,该数组具有(如他的名字所示)具有5分钟凭据的图片的URL。此请求至少需要6秒才能显示35张图片,这样就可以了。但....当存储桶中不存在图片时,我想为用户分配默认图像,例如' images / noimage.png'。 这是代码:

// Iterate an array of user images
foreach($images as $image){

    // Check if the object exists in the Bucket
    if($s3->if_object_exists($bucket, 'users/'.trim($image).'.jpg')){
        // Return the Bucket URL for this image
        $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
    } else { 

        // Return the default image
        $urls[] = 'http://www.example.com/images/noimage.png';
    }

}

条件有效,但是SLOOOOOW。使用条件" $ s3-> if_object_exists()",脚本至少需要40秒才能显示35张图像!

我修改了我的脚本,使用cURL发出请求:

// Iterate an array of user images
foreach($images as $image){

    // Setup cURL
    $ch = curl_init($s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '1 minutes') );
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    // Get Just the HTTP response code
    $res = curl_getinfo($ch,CURLINFO_HTTP_CODE);

    if($res == 200){ //the image exists
        $urls[] = $s3->get_object_url($bucket, 'users/'.trim($image).'.jpg', '5 minutes');
    }else{ // The response is 403
        $urls[] = 'http://www.example.com/images/noimage.png';
    }
}

这个经过修改的脚本需要16到18秒。这是一个很大的不同,但它仍然需要很长时间:(。

拜托,非常感谢任何帮助。

谢谢。

3 个答案:

答案 0 :(得分:1)

为什么不改变你的检查方式。将图像的位置/存储桶本地存储在数据库中,这样您就不必担心这种检查了吗?

通过这种方式,您可以最大限度地减少您正在执行的API调用的数量,现在情况为35,但随着时间的推移,这可能会呈指数级增长。并且,您不仅要为每个图像执行一次调用,而且还要为每个图像执行两次调用。这非常低效,并且依赖于您的网络连接相当快。

移动位置数据,如果图像存在与否,则在此区域的性能方面是更好的选择。此外,如果您提前存储结果,那么只需要进行一次检查就可以了。

答案 1 :(得分:1)

我认为如果您希望能够从S3读取目录类型的信息,最好使用类似s3fs的东西来将您的存储桶挂载为系统驱动器。还可以使用本地缓存配置s3fs以加快速度(如果使用EC2,则在快速临时存储上缓存)。

这将允许您轻松地执行常规PHP目录处理(DirectoryIterator等)。

如果这比您想要的更多,至少将文件名数据存储在数据库中,只是希望文件位于正确的S3位置,或者以某种方式在本地缓存单个API检查的结果,以免需要为每个类似的请求进行API调用。

答案 2 :(得分:0)

这很慢,因为你在循环的每次迭代中调用if_object_exists(),向AWS发起网络请求。

用户“thatidiotguy”说:

  

我不知道S3 API,但您是否可以要求存储桶中的文件列表并在脚本中自行匹配/搜索字符串?在PHP脚本中,34个字符串匹配测试无法接近那么长的时间。

他是对的。

而不是调用if_object_exists(),您可以在脚本开头调用get_object_list()一次 - 然后使用PHP的in_array()函数将您的用户照片网址与列表进行比较。

你应该看到加速大约百万分之百。不过,不要引用我的话。 ;)