首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将doesObjectExist()请求批处理到S3?

如何将doesObjectExist()请求批处理到S3?
EN

Stack Overflow用户
提问于 2013-09-05 14:02:38
回答 3查看 4.8K关注 0票数 4

我需要检查S3中是否存在大量项中的每个项的一组密钥。(每组密钥都与大量项中的一项相关)。

我正在使用PHP (v2)

目前,我正在为每个键调用$client->doesObjectExist(BUCKET, $key),这是一个瓶颈(每个呼叫从S3到S3的往返时间)。

我更喜欢执行类似于$client->doesObjectExist(BUCKET, $batch) where $batch = array($key1, $key2 ... $keyn)的操作,并让客户端检查所有这些键,然后返回一个响应数组(或其他类似的结构)。

我遇到了一个一些 参考文献,它是一个“批处理api”,听起来很有希望,但没有任何具体内容。我猜这可能只出现在v1 SDK中。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-05 20:52:46

您可以使用AWS通过利用底层的口吻库特性来执行并行请求。因为doesObjectExist方法实际上在这个遮罩下执行HeadObject操作。您可以通过这样的操作创建HeadObject命令组:

代码语言:javascript
运行
复制
use Aws\S3\S3Client;
use Guzzle\Service\Exception\CommandTransferException;

function doObjectsExist(S3Client $s3, $bucket, array $objectKeys)
{
    $headObjectCommands = array();
    foreach ($objectKeys as $key) {
        $headObjectCommands[] = $s3->getCommand('HeadObject', array(
            'Bucket' => $bucket,
            'Key'    => $key
        ));
    }

    try {
        $s3->execute($headObjectCommands); // Executes in parallel
        return true;
    } catch (CommandTransferException $e) {
        return false;
    }
}

$s3 = S3Client::factory(array(
    'key'    => 'your_aws_access_key_id',
    'bucket' => 'your_aws_secret_key',
));
$bucket = 'your_bucket_name';
$objectKeys = array('object_key_1', 'object_key_2','object_key_3');

// Returns true only if ALL of the objects exist
echo doObjectsExist($s3, $bucket, $objectKeys) ? 'YES' : 'NO';

如果您想要响应中的数据,而不仅仅是键是否存在,您可以更改try-catch块来执行类似的操作。

代码语言:javascript
运行
复制
try {
    $executedCommands = $s3->execute($headObjectCommands);
} catch (CommandTransferException $e) {
    $executedCommands = $e->getAllCommands();
}

// Do stuff with the command objects
foreach ($executedCommands as $command) {
    $exists = $command->getResponse()->isSuccessful() ? "YES" : "NO";
    echo "{$command['Bucket']}/{$command['Key']}: {$exists}\n";
}

用于PHP用户指南的AWS SDK中提到并行发送命令,但我也会查看炮口批次文件

票数 6
EN

Stack Overflow用户

发布于 2013-09-05 14:08:17

进行大容量检查以确定是否存在某些键的唯一方法是列出桶中的对象。

对于一个列表调用,AWS最多返回1000个键/调用,因此比对每个键执行doesObjectExist调用要快得多。但是,如果您有大量的键,并且只想检查其中的几个,那么列出桶中的所有对象是不实际的,所以在这种情况下,您唯一的选择仍然是单独检查每个对象。

问题不是PHP缺少批量功能,而是v2 S3没有实现这样的批量处理。

票数 0
EN

Stack Overflow用户

发布于 2015-01-30 03:12:17

我是建立在杰里米·林德布罗姆的回答之上的。

只想指出可以在每个命令上设置的OnComplete回调。

代码语言:javascript
运行
复制
$bucket = 'my-bucket';
$keys = array('page1.txt', 'page2.txt');

$commands = array();
foreach ($keys as $key) {
    $commands[] = $s3Client->getCommand('HeadObject', array('Bucket' => $bucket, 'Key' => $key))
        ->setOnComplete(
            function($command) use ($bucket, $key)
            {
                echo "\nBucket: $bucket\n";
                echo "\nKey: $key\n";

                // see http://goo.gl/pIWoYr for more detail on command objects
                var_dump($command->getResult());
            }
        );
}

try {
    $ex_commands = $s3Client->execute($commands);
}
catch (\Guzzle\Service\Exception\CommandTransferException $e) {
    $ex_commands = $e->getAllCommands();
}

// this is necesary; without this, the OnComplete handlers wouldn't get called (strange?!?)
foreach ($ex_commands as $command)
{
    $command->getResult();
}

如果有人能解释我为什么需要调用$command->getResult()来调用OnComplete处理程序,那就太好了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18638463

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档