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秒。这是一个很大的不同,但它仍然需要很长时间:(。
拜托,非常感谢任何帮助。
谢谢。
答案 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()
函数将您的用户照片网址与列表进行比较。
你应该看到加速大约百万分之百。不过,不要引用我的话。 ;)