5

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';
    }

}

条件有效,但慢。在条件“$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 秒。这是一个很大的区别,但仍然需要很多时间:(。

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

谢谢你。

4

3 回答 3

1

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

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

就该区域的性能而言,移动位置数据以及图像是否存在于本地是一个更好的选择。此外,如果您提前存储结果,则只需执行一次检查即可。

于 2012-09-17T19:37:05.400 回答
1

这很慢,因为您在if_object_exists()循环中的每次迭代中都进行了调用,从而启动了对 AWS 的网络请求。

用户“thatidiotguy”说:

我不了解 S3 API,但您能否要求提供存储桶中的文件列表并在脚本中自己进行字符串匹配/搜索?在 PHP 脚本中,34 个字符串匹配测试不可能花费这么长的时间。

他是对的。

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

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

于 2012-10-05T07:19:48.670 回答
1

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

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

如果这超出了您的要求,至少将文件名数据存储在数据库中,并且只期望文件位于适当的 S3 位置,或者以某种方式在本地缓存单个 API 检查的结果,以便不需要每个类似请求的 API 调用。

于 2012-09-17T20:29:12.497 回答